C# 怎样从文本提取SQL文,跳过注释

2024-10-30 12:20:19
推荐回答(3个)
回答1:

给你一个函数,这是我以前写的一个从文件中取SQL文,也是MySql的
但是因为文件中有可能会有多个SQL文,所以里面判断“;”为一条语句结束,返回SQL文的字符串数组。你要只有一条SQL文的话,改一下就可以用了

private string[] GetSqlList()
{
StreamReader objReader = new StreamReader("Insert.sql", Encoding.UTF8);
string sLine = string.Empty;
StringBuilder objStringBuilder = new StringBuilder();

while (sLine != null)
{
sLine = objReader.ReadLine();
if (!string.IsNullOrEmpty(sLine))
objStringBuilder.Append(sLine + "\n");
}
objReader.Close();
string strSQL = objStringBuilder.ToString();

if (string.IsNullOrEmpty(strSQL))
{
return new string[] { };
}

int i = 0;
ArrayList arrSql = new ArrayList();
string strTempSql = string.Empty;

//取得注释以外的有効SQL文
while (i < strSQL.Length)
{
bool bolIsBreak = false;
switch (strSQL.Substring(i, 1))
{
case "`":
int intPosition = strSQL.IndexOf(strSQL.Substring(i, 1), i);
if (intPosition == -1)
{
strTempSql += strSQL.Substring(i);
bolIsBreak = true;
}
else
{
strTempSql += strSQL.Substring(i, intPosition - i + 1);
i = intPosition;
}
break;
case "'":
goto case "`";
case "\"":
goto case "`";
case "/":
if (strSQL.Length > i + 1 && strSQL.Substring(i, 2).Equals("/*"))
{
i = strSQL.IndexOf("*/", i);
if (i == -1)
{
bolIsBreak = true;
}
i++;
}
else
{
strTempSql += strSQL.Substring(i, 1);
}
break;
case "-":
//--
if (strSQL.Length > i + 1 && strSQL.Substring(i, 2).Equals("--"))
{
i = strSQL.IndexOf("\n", i);
if (i == -1)
{
bolIsBreak = true;
}
}
else
{
strTempSql += strSQL.Substring(i, 1);
}
break;
case ";":
strTempSql = strTempSql.TrimStart('\n');
if (!string.IsNullOrEmpty(strTempSql))
{
arrSql.Add(strTempSql);
}
strTempSql = string.Empty;
break;
default:
strTempSql += strSQL.Substring(i, 1);
break;
}

if (bolIsBreak)
{
break;
}
i++;
}

strTempSql = strTempSql.TrimStart('\n');
if (!string.IsNullOrEmpty(strTempSql))
{
arrSql.Add(strTempSql);
}

string[] lstSql = new string[arrSql.Count];
for (i = 0; i < arrSql.Count; i++)
{
lstSql[i] = arrSql[i].ToString();
}

return lstSql;
}

回答2:

一般来说,读取每一行,如果开头是--就可以认为是注释,
如果串中包含/*就认为是多行注释的开始,直到遇到*/。

还有一种情况很复杂,需要判断/* */是否在字符串中
insert tab1('/*..*/', ...)
上面这句话中的/* */是不能当作注释的,因为在字符串中。

所以还需要判断注释是否在字符串中, 也就是检测单引号"'"。

过程相当复杂。

回答3:

如果用正则表达式,代码更短

///


/// 为//和/**/类型的注释着色
///

/// 输入源码
/// 格式化后的源码
private string ColorBasicComment(string src)
{
string retCode = src;
Regex r1 = new Regex(@"(^|;)([ \t]*)(//.*$)", RegexOptions.Multiline);
retCode = r1.Replace(retCode, "$1$2$3");
Regex r2 = new Regex(@"(^|[ \t]+)(/\*[^\*/]*\*/[ \t\r]*$)", RegexOptions.Multiline);
retCode = r2.Replace(retCode, new MatchEvaluator(this.ColorBasicComment2Evaluator));
return retCode;
}