Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Another thought: Microsoft provides, with Visual Studio, an assembly that can parse SQL. I've used it, and it's fairly simple to use. You might be able to use it to parse the text of your stored procedures; it can return a list of the various tokens in your statements, including the type of the token. So, it should be able to help you differentiate between what is a string of text you might be interested in vs. what is part of a comment and can be ignored. There are more details here: <a href="http://blogs.msdn.com/b/gertd/archive/2008/08/21/getting-to-the-crown-jewels.aspx" rel="nofollow">http://blogs.msdn.com/b/gertd/archive/2008/08/21/getting-to-the-crown-jewels.aspx</a>.</p> <p>Basically, from .NET, you'd open a connection to your database and query syscomments for your stored procedures' text. You'd loop through each procedure and parse it using these parser. Then you'd use the Sql100ScriptGenerator to get the tokens out of the parsed text, loop through the tokens and look for tokens whose types are either ASCII or Unicode string literals. For those strings, check their length to see if it's 20+, and if it is, flag the strings and the procs as needing further review.</p> <p>I played around with it a bit, and here is a <em>very</em> raw example to illustrate the basic principle:</p> <pre><code>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&lt;ParseError&gt; errs; IScriptFragment frag = parser.Parse(sr, out errs); if (null == frag) continue; IList&lt;TSqlParserToken&gt; tokens = gen.GenerateTokens((TSqlFragment)frag); foreach (TSqlParserToken token in tokens) { if (token.TokenType == TSqlTokenType.UnicodeStringLiteral || token.TokenType == TSqlTokenType.AsciiStringLiteral) { if (token.Text.Length &gt;= 20) Console.WriteLine("String found: " + token.Text); } } } } } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload