2013-02-28 58 views
13

我想創建一個將常規sql語句轉換爲c#對象的方法,所以我決定使用反諷來解析sql語句,然後我將該語句作爲一個Action返回,該Action包含聲明和它取決於類型解析SQL語句的反諷

這裏的值是我的非完成的代碼[因爲我很沮喪,因爲我不知道該怎麼辦,然後]

private List<Action> ParseStatement(string statement) 
{ 
    var parser = new Parser(new SqlGrammar()); 
    var parsed = parser.Parse(statement); 
    var status = parsed.Status; 

    while (parsed.Status == ParseTreeStatus.Parsing) 
    { 
     Task.Yield(); 
    } 

    if (status == ParseTreeStatus.Error) 
     throw new ArgumentException("The statement cannot be parsed."); 

    ParseTreeNode parsedStmt = parsed.Root.ChildNodes[0]; 

    switch (parsedStmt.Term.Name) 
    { 
     case "insertStmt": 
      var table = parsedStmt.ChildNodes.Find(x => x.Term.Name == "Id").ChildNodes[0].Token.ValueString; 
      var valuesCount = 
       parsedStmt.ChildNodes.Find(x => x.Term.Name == "insertData").ChildNodes.Find(
        x => x.Term.Name == "exprList").ChildNodes.Count; 
      var values = parsedStmt.ChildNodes.Find(x => x.Term.Name == "insertData").ChildNodes.Find(
        x => x.Term.Name == "exprList").ChildNodes; 
      foreach (var value in values) 
      { 
       string type = value.Token.Terminal.Name; 
      } 
      break; 
    } 

    return null; 
} 

private Type ParseType(string type) 
{ 
    switch (type) 
    { 
     case "number": 
      return typeof (int); 
     case "string": 
      return typeof (string); 
    } 

    return null; 
} 

所以這裏的問題是:如何我可以利用Irony將字符串SQL語句轉換爲ac#對象嗎?

這裏是什麼我想要實現的一個示例:

INSERT INTO人員VALUES(4, 'Nilsen的', '約翰', '巴肯2', '斯塔萬格')

並把它轉化爲

return new Action<string type, string table, int val1, string val2, string val3, string val4, string val5>; 

動態取決於什麼方法從宣讀的聲明。

我希望我已經很好地解釋了我的想法,所以你可以幫助我,如果有什麼不清楚的地方,請告訴我,我會盡力解釋它。

+5

我猜你的出發點應該是得到一個合適的SQL語法,並將其轉換爲Irony可以理解的語法格式。這不是件容易的事。你需要做很多不容易受挫的人的工作。但這是可以完成的。 – 2013-02-28 01:46:28

+0

我已經有SQLGrammar,但問題是解析每個語句,插入,更新,創建...然後返回它的內容[在其他用途​​中用於C#] – 2013-02-28 01:53:02

+0

您的問題更多地涉及讓Irony解析您的SQL語句,或更多來執行基於解析結果的轉換?你對從反諷中獲得的AST滿意嗎?你能展示一些你正在使用的相關SQL語法嗎? – 2013-07-08 18:52:37

回答

1

如果你不這樣做是一個有趣的練習,我會建議使用Linq to SQL來生成您的存根類或實體框架作爲註釋中提到的醉酒代碼猴。

這裏有一個很好的文章,讓你開始:​​

1

我試圖解析與反諷SQL爲好。我放棄了,因爲在反諷樣本SQL語法分析程序不處理:熱膨脹係數,排序列數,一半的特殊之類的語句

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

雖然我有一個偉大的時間來學習反諷,我沒有編碼排序以正確實施所有上述部分。

我結束了使用微軟提供的SQL解析庫。下面的LINQPad 5示例代碼:

// Add a reference to 
// C:\Program Files (x86)\Microsoft SQL Server\130\SDK\Assemblies\ 
// Microsoft.SqlServer.TransactSql.ScriptDom.dll 
// 
// https://blogs.msdn.microsoft.com/gertd/2008/08/21/getting-to-the-crown-jewels/ 

public void Main() 
{ 
    var sqlFilePath = @"C:\Users\Colin\Documents\Vonigo\database-scripts\Client\Estimate\spClient_EstimateAddNew.sql"; 
    bool fQuotedIdenfifiers = false; 
    var parser = new TSql100Parser(fQuotedIdenfifiers); 

    string inputScript = File.ReadAllText(sqlFilePath); 
    IList<ParseError> errors; 
    using (StringReader sr = new StringReader(inputScript)) 
    { 
     var fragment = parser.Parse(sr, out errors); 
     fragment.Dump(); 
    } 
}