2012-07-31 19 views
12

私は一時テーブルを作成し、同じコマンドと接続を使用して別の2つのステートメントを作成しています。ただし、作成する前にパラメータを挿入してテーブルを作成すると、「無効なオブジェクト名」が表示されます。私はそれを作成した後に追加する場合、それは正常に動作します。パラメータを持つコマンドを使用するときに一時テーブルの '無効なオブジェクト名'

一時テーブルはセッション全体を持続するはずですので、パラメータがコマンドオブジェクトに追加されたときに重要なことはわかりません。

は失敗します。

 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

+0

SqlExceptionがスローされました "無効なオブジェクト名 '#Test'" – mford

+0

はい、SQLインジェクションに対する追加の保護機能が追加されているため、標準です。必要な場合は、ストアドプロシージャを使用して作業を実行したり、コマンドを1つのクエリに結合したりすることができます。 – Trisped

答えて

0

最初の実行の状態は、各パラメータを使用する必要があると主張しているため、失敗している可能性があります。

+0

他のステートメントでは、このように動作しません。コマンドオブジェクトは任意の数のパラメータを持つことができ、ステートメントで使用されているものだけを使用します。 – mford

+0

また、作成は失敗していません。詳細は上記の編集を参照してください。 – mford

7

問題は実際には "exec sp_executesql"ステートメントにあります。 ADOは、sqlCommandで宣言されたパラメータがあることを検出すると、デフォルトで "exec"ではなく "sp_executesql"を使用します。しかしこの場合、最初のコマンドはTEMPORALテーブルを作成しており、既知のように、一時テーブルはストアドプロシージャ(sp_executesql)内でのみ有効であり、終了時に削除されます。したがって、結果的に、2番目のINSERTステートメントは、最初のサンプルコードでは有効ではありません。 2つ目は、一時テーブルが正常に作成され、insert文が正常に実行されます。それが役に立てば幸い。

関連する問題