另一个想法:Microsoft通过Visual Studio提供了可以解析sql的程序集。我已经用过了,而且使用起来很简单。您也许可以使用它来解析存储过程的文本;它可以返回语句中各种标记的列表,包括标记的类型。因此,它应该能够帮助您区分您可能会感兴趣的文本字符串与注释中哪些内容可以忽略。
基本上,从.NET,您将打开与数据库的连接,并查询syscomments以获取存储过程的文本。您将遍历每个过程,并使用这些解析器对其进行解析。然后,您将使用sql100ScriptGenerator从解析的文本中获取标记,遍历标记并查找其类型为ASCII或Unicode字符串文字的标记。对于那些字符串,请检查它们的长度以查看其长度是否超过20,如果是20,则将这些字符串和proc标记为需要进一步检查。
我玩了一下,这是一个 非常 原始的示例来说明基本原理:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.sqlClient;
using Microsoft.Data.Schema;
using Microsoft.Data.Schema.ScriptDom;
using Microsoft.Data.Schema.ScriptDom.sql;
namespace FindHardCodedStrings
{
class Program
{
static void Main(string[] args)
{
using (sqlConnection conn = new sqlConnection())
{
sqlConnectionStringBuilder bldr = new sqlConnectionStringBuilder();
bldr.DataSource = "localhost\\sqlexpress";
bldr.InitialCatalog = "msdb";
bldr.IntegratedSecurity = true;
conn.ConnectionString = bldr.ConnectionString;
sqlCommand cmd = conn.CreateCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "select [text] from syscomments";
sqlDataAdapter da = new sqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
Tsql100Parser parser = new Tsql100Parser(false);
sql100ScriptGenerator gen = new sql100ScriptGenerator();
gen.Options.sqlVersion = sqlVersion.sql100;
foreach (DaTarow proc in ds.Tables[0].Rows)
{
string txt = proc[0].ToString();
using (System.IO.TextReader sr = new System.IO.StringReader(txt))
{
IList<ParseError> errs;
IScriptFragment frag = parser.Parse(sr, out errs);
if (null == frag)
continue;
IList<TsqlParserToken> tokens = gen.GenerateTokens((TsqlFragment)frag);
foreach (TsqlParserToken token in tokens)
{
if (token.TokenType == TsqlTokenType.UnicodeStringLiteral || token.TokenType == TsqlTokenType.AsciiStringLiteral)
{
if (token.Text.Length >= 20)
Console.WriteLine("String found: " + token.Text);
}
}
}
}
}
}
}
}