2015-03-19 94 views
2

表,即C#:查找涉及給定一個SQL查詢變量SQL查詢

string mySQLQuery = "SELECT TableA.Field1, TableA.Field2,..., TableB.Field1, TableB.Field2,.... FROM TableA LEFT OUTER JOIN TableB ON TableA.Field1 = TableB.Field1" 

有沒有筆直的路我可以提取查詢中的字段和表名在兩個列表?所以:

列表「字段」:

  • 所有字段從表A,表B(和其他人我可以通過參加補充)與他們的表前綴(即使在一個簡單的只有一個表'SELECT * FROM TableA',我仍然需要'TableA。'前綴)。

  • 所有字段從表B與它們的表前綴,通過將它們添加到通常的fieldList.Add()方式通過循環的方式。

清單 「表格」:

  • 在平時tablesList.Add查詢中涉及的所有表()通過循環方式。

我的第一個辦法是讓很多子和比較,即,尋找FROM,然後修剪離開後,子,直到第一個空格,然後加入,那麼微調,那麼第一串,直到空間...,但這似乎並不正確。

重新編輯

我知道我可以從所有屬性INFORMATION_SCHEMA.COLUMNS所有字段(是後話),但問題是,對於查詢我需要知道的表。我的步驟應該是:

  1. 查詢「SELECT [田] FROM [表]」來自一個多行TextBox,所以我可以寫一個SQL查詢來獲取我想要的字段。我通過txtMyQuery.Text屬性獲取字符串。

  2. 查找SELECT查詢中的字段,並在FROM子句中查找屬於哪個表。

  3. 在字符串列表中存儲類似[Table]。[Field]的字段使用strFields.Add()方法列出strFields = new List()

  4. 然後,通過列表類似的方式重複:當然

    for (int i = 0; i < fieldList.Count; i++) 
    { 
        string mySqlQuery = "SELECT Table_Name, Column_Name, Data_Type FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE (COLUMN_NAME + "." + TABLE_NAME) ='" + fieldList[i] + "'"; 
    
        //Commit query, get results in a gridview, etc. 
    
    } 
    
+1

解析sql與解析HTML類似。我會看看是否有可用的庫。我沒有找到一個免費的。只是:http://www.sqlparser.com/ – 2015-03-19 08:34:36

+0

如果sql語句是'SELECT * FROM TableA',輸出應該如何?你還需要JOIN和WHERE子句中的字段,還是隻需要SELECT子句中的字段? 如果語句是'SELECT * FROM TableA INNER JOIN TableB ON(TableA.BId = TableB.Id)',會發生什麼? – 2015-03-19 08:36:28

+0

我只需要SELECT子句中的字段將它們存儲在列表中。 WHERE,HAVING等等,即使在SELECT子句中沒有像你所建議的那樣沒有字段的引用時也是不需要的。 在SELECT * FROM表A的情況下,我需要一個輸出與TableA.Field1,TableA.Field2,TableA.Field3,... – Mario 2015-03-19 08:39:19

回答

0

表:

SELECT TABLE_NAME FROM information_schema.TABLES 

領域:

SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = N'Your Table' 
+0

請參閱reedit ...問題是需要提取「您的表」 – Mario 2015-03-19 09:27:26

+0

好的,那麼我認爲唯一的解決方法是創建您自己的解析器或搜索一個。 – 2015-03-19 09:41:11

0

好了,過了一段時間,我找到了一些方法來實現這個目標......我會在改進解決方案時解決這個問題(即,現在如果我們使用* SELECT * FROM TableA *等選項, ,不支持別名,並且SELECT中的所有字段都應該是[table]。[字段],但會給出我想要實現的內容的一個概念):

這樣,我在文本框中編寫SQL語句,我將它傳遞到新窗體上以檢查查詢的實際結果(如果需要,通過單擊「預覽」按鈕),然後使用我想要檢索的SCHEMA數據填充datagridview。

感謝各位的支持!

private void btnQuery_Click(object sender, EventArgs e) 
    { 

     string strSql = this.txtQuery.Text; 

     DataTable dt = new DataTable(); 

     String conStr = "Data Source=(LocalDB)\\v11.0;AttachDbFilename=|DataDirectory|\\TestDB.mdf;Integrated Security=True;Connect Timeout=30"; 
     using (SqlConnection conn = new SqlConnection(conStr)) 
     { 
      //with the call to strSQLSchema, we get the table involved in the query, to retrieve the fields and properties 
      SqlCommand cmd = new SqlCommand(strSQLSchema(strSql), conn); 
      SqlDataAdapter adapter = new SqlDataAdapter(cmd); 
      try 
      { 
       adapter.Fill(dt); 
      } 

      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 

     this.dgvColumns.DataSource = dt; 

    } 

    private void btnPreview_Click(object sender, EventArgs e) 
    { 
     //We must pass the sql query to preview 
     string strSql = this.txtQuery.Text; 
     SQLQueryDataPreview qp = new SQLQueryDataPreview(strSql); 
     qp.Show(); 
    } 

    private string strSQLSchema(string sqlQuery) 
    { 
     //we cut the "SELECT " start 
     sqlQuery = sqlQuery.ToUpper(); 
     sqlQuery = sqlQuery.Substring(7); 
     //we take all the fields until the FROM 
     int myIndex = sqlQuery.IndexOf("FROM"); 

     sqlQuery = sqlQuery.Substring(0, myIndex); 
     sqlQuery = sqlQuery.Trim(); 
     sqlQuery = sqlQuery.Replace(" ", string.Empty); 
     sqlQuery = sqlQuery.Replace("\r\n", string.Empty); 

     //Here we add all fields to a list... so far, "*" is not allowed, and all fields should be written [Table].[Name] 
     string[] myFields = sqlQuery.Split(new char[] {' ', ','}); 

     List <string> myTables = new List<string>(); 

     //We will use this WHERE to find the fields in the SCHEMA. This WHERE first sentence helps to construct a valid where 
     //and avoid problems with the 'OR' clause in each loop. 

     string myWhere = "TABLE_NAME + '.' + COLUMN_NAME = ''"; 

     for (int i = 0; i < myFields.Count(); i++) 
     { 
      //here we take the table prefix and add it to an array 
      int tableIndex = myFields[i].IndexOf("."); 
      if (tableIndex != -1) 
      { 
       myTables.Add(myFields[i].Substring(0, tableIndex)); 
       myWhere += "OR (TABLE_NAME + '.' + COLUMN_NAME = '" + myFields[i] + "')"; 
      }    
     } 

     //this is a List where we keep the tables derivated from names. We just copy the list generated before with a DISTINCT to eliminate duplicates. 
     myTables = myTables.Distinct().ToList(); 

     string schema = "SELECT Table_Name, Column_Name, Data_Type FROM INFORMATION_SCHEMA.COLUMNS WHERE " + myWhere; 
     return schema; 
    } 

}