ZhiYeJianKang_PeiXun/cyqdata-master/SQL/SqlSyntax.cs

329 lines
14 KiB
C#
Raw Permalink Normal View History

2025-02-20 15:41:53 +08:00
using System;
using System.Collections.Generic;
using System.Text;
namespace CYQ.Data.SQL
{
/// <summary>
/// SQL<51><EFBFBD><EFB7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
internal class SqlSyntax
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public static SqlSyntax Analyze(string sql)
{
return new SqlSyntax(sql);
}
public string SqlText;
private SqlSyntax(string sql)
{
SqlText = sql;
FormatSqlText(sql);
}
public string TableName = string.Empty;
public string Where = string.Empty;
public bool IsInsert = false;
public bool IsInsertInto = false;
public bool IsSelect = false;
public bool IsUpdate = false;
public bool IsDelete = false;
public bool IsFrom = false;
public bool IsGetCount = false;
// bool IsAll = false;
public bool IsTopN = false;
public bool IsDistinct = false;
public bool IsLimit = false;
public bool IsOffset = false;
public bool IsWhere = false;
public bool IsOrder = false;
public int TopN = -1;
public int PageIndex = 0;
public int PageSize = 0;
public List<string> FieldItems = new List<string>();
void FormatSqlText(string sqlText)
{
string[] items = sqlText.Split(' ');
foreach (string item in items)
{
#region MyRegion
switch (item.ToLower())
{
case "insert":
IsInsert = true;
break;
case "into":
if (IsInsert)
{
IsInsertInto = true;
}
break;
case "select":
IsSelect = true;
break;
case "update":
IsUpdate = true;
break;
case "delete":
IsDelete = true;
break;
case "from":
IsFrom = true;
break;
case "count(*)":
case "count(0)":
case "count(1)":
IsGetCount = true;
break;
case "limit":
if (IsSelect && (IsFrom || IsWhere))
{
IsLimit = true;
}
break;
case "offset":
if (IsLimit)
{
IsLimit = false;
IsOffset = true;
}
break;
case "order":
if (IsFrom || IsWhere)
{
IsOrder = true;
}
break;
case "by":
case "where":
if (IsFrom || IsUpdate)
{
IsFrom = false;
IsWhere = true;
int startIndex = sqlText.LastIndexOf(" " + item + " ") + item.Length + 2;
int limit = sqlText.IndexOf(" limit ", startIndex, StringComparison.OrdinalIgnoreCase);
if (limit == -1)
{
Where = sqlText.Substring(startIndex);
}
else
{
Where = sqlText.Substring(startIndex, limit - startIndex);
}
if (item.ToLower() == "by")
{
Where = "order by " + Where;
}
}
break;
case "top":
if (IsSelect && !IsFrom)
{
IsTopN = true;
}
break;
case "distinct":
if (IsSelect && !IsFrom)
{
IsDistinct = true;
}
break;
case "set":
if (IsUpdate && !string.IsNullOrEmpty(TableName) && FieldItems.Count == 0)
{
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Update<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD>ֵ
int start = sqlText.IndexOf(item) + item.Length;
int end = sqlText.ToLower().IndexOf("where");
string itemText = sqlText.Substring(start, end == -1 ? sqlText.Length - start : end - start);
int quoteCount = 0, commaIndex = 0;
for (int i = 0; i < itemText.Length; i++)
{
if (i == itemText.Length - 1)
{
string keyValue = itemText.Substring(commaIndex).Trim();
if (!FieldItems.Contains(keyValue))
{
FieldItems.Add(keyValue.Trim());
}
}
else
{
switch (itemText[i])
{
case '\'':
quoteCount++;
break;
case ',':
if (quoteCount % 2 == 0)//˫<><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>
{
string keyValue = itemText.Substring(commaIndex, i - commaIndex).Trim();
if (!FieldItems.Contains(keyValue))
{
FieldItems.Add(keyValue);
}
commaIndex = i + 1;
}
break;
}
}
}
#endregion
}
break;
default:
if (IsOffset)
{
if (!int.TryParse(item, out PageIndex))
{
PageIndex = 0;
}
}
else if (IsLimit)
{
if (!int.TryParse(item, out PageSize))
{
PageSize = 0;
}
}
if (!IsWhere)
{
if (IsTopN && TopN == -1)
{
if (int.TryParse(item, out TopN))//<2F><>ѯTopN
{
PageSize = TopN;
}
IsTopN = false;//<2F>ر<EFBFBD>topN
}
else if ((IsFrom || IsUpdate || IsInsertInto) && string.IsNullOrEmpty(TableName))
{
TableName = item.Split('(')[0].Trim();//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
else if (IsSelect && !IsFrom)//<2F><>ȡ<EFBFBD><C8A1>ѯ<EFBFBD><D1AF><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
#region Select <EFBFBD>ֶ<EFBFBD><EFBFBD>Ѽ<EFBFBD>
switch (item)
{
case "*":
case "count(*)":
case "count(0)":
case "count(1)":
case "distinct":
break;
default:
fieldText.Append(item + " ");
break;
}
#endregion
}
else if (IsInsertInto && !string.IsNullOrEmpty(TableName) && FieldItems.Count == 0)
{
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Insert Into<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD>ֵ
int start = sqlText.IndexOf(TableName) + TableName.Length;
int end = sqlText.IndexOf("values", start, StringComparison.OrdinalIgnoreCase);
if (end == -1)
{
end = sqlText.IndexOf("select", start, StringComparison.OrdinalIgnoreCase);
if (end == -1) { break; }
}
string keys = sqlText.Substring(start, end - start).Trim();
string[] keyItems = null;//insert into aaa values('','');
if (keys.Length > 2)//<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD>ա<EFBFBD>
{
keyItems = keys.Substring(1, keys.Length - 2).Split(',');//ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٰ<EFBFBD><D9B0><EFBFBD><EFBFBD>ŷָ<C5B7><D6B8><EFBFBD>
}
string values = sqlText.Substring(end + 6).Trim();
if (IsSelect && IsFrom)
{
end = values.IndexOf("from");
if (end > 0)
{
//insert into ...select ...from ģʽ
values = values.Substring(0, end);//ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
else
{
// insert into ... values ģʽ<C4A3><CABD>
values = values.Substring(1, values.Length - 2);//ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
if (keyItems == null)
{
keyItems = new string[values.Split(',').Length];
}
int quoteCount = 0, commaIndex = 0, valueIndex = 0;
#region get values
for (int i = 0; i < values.Length; i++)
{
if (valueIndex >= keyItems.Length)
{
break;
}
if (i == values.Length - 1)
{
string value = values.Substring(commaIndex).Trim();
keyItems[valueIndex] += "=" + value;
}
else
{
switch (values[i])
{
case '\'':
quoteCount++;
break;
case ',':
if (quoteCount % 2 == 0)//˫<><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>
{
string value = values.Substring(commaIndex, i - commaIndex).Trim();
keyItems[valueIndex] += "=" + value;
commaIndex = i + 1;
valueIndex++;
}
break;
}
}
}
#endregion
FieldItems.AddRange(keyItems);
#endregion
}
}
break;
}
#endregion
}
#region Select <EFBFBD>ֶν<EFBFBD><EFBFBD><EFBFBD>
if (fieldText.Length > 0)
{
if (FieldItems.Count == 0)
{
string[] fields = fieldText.ToString().Split(',');
foreach (string item in fields)
{
FieldItems.Add(item.Trim());
}
}
fieldText.Length = 0;
}
#endregion
}
private StringBuilder fieldText = new StringBuilder();
}
}