2011-02-25 29 views
3

我需要在SQL字符串中查找實際外部'from'的索引。這裏有一些SQL字符串的例子,我會查找實際的FROM:查找SQL語句字符串中的外部FROM子句的索引

select * from table --easy 
select *, (select top 1 col1 from anothertable) as col1 from table 
select * from table, (select col1 from anothertable) as anothertable 
select * from table where col1=(select top 1 col1 from anothertable) 

我確定有更多有效的SQL語句使用子選擇。我認爲我需要的是一個正則表達式或解析器,它知道最外層的'from'和不同的'from'之間的區別。當然,我可能沒有考慮找到外部'from'的其他陷阱,所以任何輸入都將被讚賞。

回答

0

假設您想要查找的「from」是唯一一個括號外的字符,您可以逐字通過字符串並計算括號(打開時爲+1,關閉時爲-1)。當你的支架計數器爲0時發現「from」,它應該是正確的。

+0

哇,太簡單了!謝謝。 – sagesmith7 2011-02-26 02:39:34

+1

@ sagesmith7 - 只要您的查詢沒有任何包含括號或表格名稱的註釋,例如'[non standard :-)]'或者可能有很多其他邊緣案例! – 2011-02-26 11:38:01

4

您可以使用Microsoft.Data.Schema.ScriptDom。概念應用的邊緣粗糙。

using System; 
using System.Collections.Generic; 
using System.IO; 
using Microsoft.Data.Schema.ScriptDom; 
using Microsoft.Data.Schema.ScriptDom.Sql; 

namespace ConsoleApplication1 
{ 
    internal class Program 
    { 
     public static void Main(string[] args) 
     { 
      string[] queries = 
       { 
        @"select * from table1;", 
        /*Test multiline*/ 
        @"select *, 
           (select top 1 col1 from anothertable) as col1 from table1;" 
        , 
        @"select * from table1, (select col1 from anothertable) as anothertable;", 
        @"select * from table1 where col1=(select top 1 col1 from anothertable)", 
        /*Test invalid syntax ("table" is a reserved word)*/ 
        @"select * from table where col1=(select top 1 col1 from anothertable)" 
       }; 

      foreach (string query in queries) 
      { 
       Parse(query); 
      } 

      Console.ReadKey(); 
     } 

     private static void Parse(string query) 
     { 
      Console.WriteLine(@"------------------------------------------"); 
      Console.WriteLine(@"Parsing statement ""{0}""", query); 

      var parser = new TSql100Parser(false); 

      IList<ParseError> errors; 
      IScriptFragment result = parser.Parse(new StringReader(query), out errors); 

      if (errors.Count > 0) 
      { 
       Console.WriteLine(@"Errors encountered: ""{0}""", errors[0].Message); 
       return; 
      } 


      TSqlStatement statement = ((TSqlScript) result).Batches[0].Statements[0]; 

      if (statement is SelectStatement) 
      { 
       TableSource tableSource = (((QuerySpecification)((SelectStatement)statement).QueryExpression).FromClauses[0]); 

       Console.WriteLine(@"Top level FROM clause at Line {0}, Column {1} (Character Offset {2})", 
            tableSource.StartLine, tableSource.StartColumn, tableSource.StartOffset); 
       Console.WriteLine(); 
       Console.WriteLine(); 

      } 
     } 
    } 
} 

輸出

------------------------------------------ 
Parsing statement "select * from table1;" 
Top level FROM clause at Line 1, Column 15 (Character Offset 14) 


------------------------------------------ 
Parsing statement "select *, 
           (select top 1 col1 from anothertable) as col1 from 
table1;" 
Top level FROM clause at Line 2, Column 82 (Character Offset 93) 


------------------------------------------ 
Parsing statement "select * from table1, (select col1 from anothertable) as ano 
thertable;" 
Top level FROM clause at Line 1, Column 15 (Character Offset 14) 


------------------------------------------ 
Parsing statement "select * from table1 where col1=(select top 1 col1 from anoth 
ertable)" 
Top level FROM clause at Line 1, Column 15 (Character Offset 14) 


------------------------------------------ 
Parsing statement "select * from table where col1=(select top 1 col1 from anothe 
rtable)" 
Errors encountered: "Incorrect syntax near table." 
0

考慮到,從可以選擇子句爲SP的字段名,別名或名稱中occure,以及。 如果TABLE從字段中選擇,則從select中選擇TABLE是有效的。