2012-07-31 39 views
12

我正在創建一個臨時表並使用相同的命令和連接使用兩個單獨的語句來填充臨時表。但是,如果我在創建之前插入參數並創建了表,我會收到'無效的對象名'。如果我在創建後添加它,它工作正常。當使用帶參數的命令時,臨時表的'無效對象名'

臨時表應該持續整個會話,所以當參數添加到命令對象時,我看不出什麼問題。

失敗:

 using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TEST;Integrated Security=True;")) 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      conn.Open(); 

      cmd.Parameters.Add(new SqlParameter("@ID", 1234)); 

      cmd.CommandText = "CREATE TABLE #Test (ID INT NOT NULL PRIMARY KEY, I INT NOT NULL)"; 
      cmd.ExecuteNonQuery(); 

      cmd.CommandText = "INSERT INTO #Test VALUES (@ID, 1)"; 
      cmd.ExecuteNonQuery(); 

      ..... more code that uses the table 

     } 

WORKS:

 using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TEST;Integrated Security=True;")) 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      conn.Open(); 

      cmd.CommandText = "CREATE TABLE #Test (ID INT NOT NULL PRIMARY KEY, I INT NOT NULL)"; 
      cmd.ExecuteNonQuery(); 

      cmd.Parameters.Add(new SqlParameter("@ID", 1234)); 

      cmd.CommandText = "INSERT INTO #Test VALUES (@ID, 1)"; 
      cmd.ExecuteNonQuery(); 

      ..... more code that uses the table 

     } 

編輯:

SQL事件探查闡明這更多的光線。

如果該命令有任何參數,則底層代碼將發出「exec sp_executesql」。如果清除參數,則底層代碼會發出更直接的「CREATE TABLE」。臨時表在sp_executesql後清理,這解釋了我在這裏看到的內容。

對我來說,這將是SqlCommand(或相關)代碼中的一個錯誤,但由於我現在有一個解釋,我可以繼續前進。

+0

你得到了什麼錯誤信息 – HatSoft 2012-07-31 17:52:43

+0

這是一個拋出的SqlException,「無效的對象名'#Test'」 – mford 2012-07-31 18:56:11

+0

是的,這是標準的,因爲它增加了少量的SQL注入額外保護。如果需要,您可以使用存儲過程來完成這項工作,或將這些命令組合成一個查詢。 – Trisped 2012-07-31 19:54:34

回答

0

我懷疑第一次執行的狀態失敗,因爲它堅持必須使用每個參數。

+0

它不適用於任何其他聲明。命令對象可以具有任意數量的參數,並且只使用語句中使用的那些參數。 – mford 2012-07-31 18:52:41

+0

另外,創建不失敗。請參閱上面的編輯瞭解更多信息 – mford 2012-07-31 20:05:25

7

問題實際上出現在「exec sp_executesql」語句中。當ADO檢測到在sqlCommand中聲明瞭參數時,默認使用「sp_executesql」而不是「exec」。但是在這種情況下,第一個命令是創建一個TEMPORAL表,並且如所知,臨時表僅在存儲過程(sp_executesql)內有效,並在退出時被刪除。因此,第二個INSERT語句在第一個示例代碼中不再有效。在第二種情況下,臨時表已成功創建,插入語句正常執行。希望能幫助到你。

相關問題