none
「INDETITY」の設定した項目をインサート文の値でデータベースに登録するためにはどのように記述すればよいのでしょうか? RRS feed

  • 質問

  • INDETITYをフィルドに設定した場合で、設定した項目を含めてインサートしたい場合にはどのように

    ASP.NETで記述すればよいのか、よろしくお願いします。

     

    条件は以下のうようです。

     

    データベースのフィールドの型で

    データ型をnumericで

    IDENTITYを「はい」で設定したフィールドの項目を

    仮にその項目をpid、テーブル名をTBL1としてDBを定義します。

     

    1.ASP.net2.0のsqldatasourceのツールを使って

    インサート文で

    insert into TBL1(pid) values("1");

    と記述すると、

    「IDENTITY_INSERT が ON のときに限りテーブル 'TBL1' の ID 列に明示的な値を指定できます。」

    とエラーが出ます。

    ちなみに、insertcommand で

    IDENTITY_INSERT TBL1 ON;insert into TBL1(pid) values("1");

    と記述しています。

     

    ※1がインサートコマンドなので、「IDENTITY_INSERT TBL1 ON」の記述ができないのでしょか

     

    2. SqlConnection sqlCon = new SqlConnection(strCon);を使って上記と同じ

    SQL分を使っても同様にIDENTITY_INSERT が ON が有効にならないようです。

     

    3.SQL Server ManagementのSQLコマンドで

    IDENTITY_INSERT TBL1 ON

    insert into TBL1(pid) values("1");

    すでにpidに同じ番号がある場合は、インストールされませんが

    pidの値がDBにない場合はインストールされます。

    また、複数のインサート文があっても問題なくインサートされます。

    2008年3月10日 8:41

回答

  • たぶん、想像なのですが、SqlDataSourceではInsertを実行する度に接続がopenしてcloseするのではないでしょうか。そのため、以前実行したSET IDENTITY_INSERT ・・・が無効になってしまう気がします。ちなみに、以下のコードでは、問題なく挿入できました。

     

       SqlConnection conn = null;

     

       try
       {
        conn = new SqlConnection(SqlDataSource1.ConnectionString);


        SqlCommand cmd = new SqlCommand("SET IDENTITY_INSERT [TEST]ON;INSERT INTO [TEST] ([TESTID], [TEST1], [TEST2], [TEST3]) VALUES (" + TextBox1.Text + ", 1, 2, 3)", conn);

        

        conn.Open();
        cmd.ExecuteNonQuery();

     

        cmd.CommandText = "INSERT INTO [TEST] ([TESTID], [TEST1], [TEST2], [TEST3]) VALUES (" + (int.Parse(TextBox1.Text) + 1).ToString() + ", 1, 2, 3)";
        cmd.ExecuteNonQuery();
       }
       catch (Exception ex)
       {
        throw ex;
       }
       finally
       {
        conn.Close();
       }

    2008年3月11日 16:13
    モデレータ

すべての返信

  •  himi07 さんからの引用

    1.ASP.net2.0のsqldatasourceのツールを使って

    ちなみに、insertcommand で

    IDENTITY_INSERT TBL1 ON;insert into TBL1(pid) values("1");

    と記述しています。

     

    試していませんが、「SET IDENTITY_INSERT TBL1 ON;insert ・・・」としても結果は同じでしょうか?

    2008年3月10日 9:38
  • お返事ありがとうございます。

     

    記述不足ですいません。

     

    SET IDENTITY_INSERT TBL1 ON;insert ・・・

    で記述してだめでしたので、

    IDENTITY_INSERT TBL1 ON;insert into TBL1(pid) values("1");

    でもやってみましたが、どちらもだめでした。

     

    ちなみに、

    connectionstringの部分は

    Security=True;User Instance=True

    で接続しています。
    2008年3月11日 0:44
  •  himi07 さんからの引用

    SET IDENTITY_INSERT TBL1 ON;insert ・・・

    で記述してだめでしたので、

     

    こちらで試したところうまくいきました。どのようなエラーメッセージが表示されているのでしょうか?

    2008年3月11日 3:19
    モデレータ
  •  himi07 さんからの引用

    SET IDENTITY_INSERT TBL1 ON;insert ・・・

    で記述してだめでしたので、

    IDENTITY_INSERT TBL1 ON;insert into TBL1(pid) values("1");

    で接続しています。

     

    気になったので、似たような構成のテーブルでテストしてみました。

    結果、「SET IDENTITY_INSERT ・・・」はうまく動作し、「IDENTITY_INSERT ・・・」はエラーでした。

     

    ちなみに上記SQLは「;」が全角?になっております。コードをそのままコピーしているのであれば、「';' の近くに無効な構文があります。」というエラーになると思います。。。

    2008年3月11日 4:23
  •  

     GENZ0 さんからの引用

     

    気になったので、似たような構成のテーブルでテストしてみました。

    結果、「SET IDENTITY_INSERT ・・・」はうまく動作し、「IDENTITY_INSERT ・・・」はエラーでした。

     

    ちなみに上記SQLは「;」が全角?になっております。コードをそのままコピーしているのであれば、「';' の近くに無効な構文があります。」というエラーになると思います。。。

    trapemiya / GENZ0様ご返事ありがとうございます。

     

    SQLは「;」は半角で記述しています。

     

    結果は確かに、SET IDENTITY_INSERT ・・・」は通っているようで、こちらでは、それ以降のインサート文でエラーになっています。

    このSETの部分が利いていないように思っているのですが??

     

    ちなみにエラーメッセージは、

    列リストが使用されていて、IDENTITY_INSERT が ON のときに限り、テーブル xxxx の ID 列に明示的な値を指定できます。

    です。

     

    2008年3月11日 7:09
  • たぶん、想像なのですが、SqlDataSourceではInsertを実行する度に接続がopenしてcloseするのではないでしょうか。そのため、以前実行したSET IDENTITY_INSERT ・・・が無効になってしまう気がします。ちなみに、以下のコードでは、問題なく挿入できました。

     

       SqlConnection conn = null;

     

       try
       {
        conn = new SqlConnection(SqlDataSource1.ConnectionString);


        SqlCommand cmd = new SqlCommand("SET IDENTITY_INSERT [TEST]ON;INSERT INTO [TEST] ([TESTID], [TEST1], [TEST2], [TEST3]) VALUES (" + TextBox1.Text + ", 1, 2, 3)", conn);

        

        conn.Open();
        cmd.ExecuteNonQuery();

     

        cmd.CommandText = "INSERT INTO [TEST] ([TESTID], [TEST1], [TEST2], [TEST3]) VALUES (" + (int.Parse(TextBox1.Text) + 1).ToString() + ", 1, 2, 3)";
        cmd.ExecuteNonQuery();
       }
       catch (Exception ex)
       {
        throw ex;
       }
       finally
       {
        conn.Close();
       }

    2008年3月11日 16:13
    モデレータ
  •  

    trapemiya様

    ありがとうございます。

     trapemiya さんからの引用

     

        cmd.CommandText = "INSERT INTO [TEST] ([TESTID], [TEST1], [TEST2], [TEST3]) VALUES (" + (int.Parse(TextBox1.Text) + 1).ToString() + ", 1, 2, 3)";

     

    こちらでも、記述してもらったようなインサート文ではこちらでも確認できました。

    ありがとうございました。

     

    こちらでのテストした結果ですが、

    INTO [TEST] ([TESTID], [TEST1], [TEST2], [TEST3]) のようにフィールドを記述しないと、INDETITYがある場合は、

    インサート文のフィールドを指定している部分を省略すると、インサートは失敗してしまうようです。

    (もちろん valuesに設定されている値はテーブルと同一であります。)

     

    また、INDETITYに設定した項目が一時的に解除しているようですので、何度でも追加されますので

    INDETITYとしているフィールドには、同じ値が入ってしまいますので、注意が必要だと思います。

    このSQLを使わなければいけない場合は、テーブルをバックアップしておいたものを戻す場合などと考えられるので

    テーブル内を削除しておくか、インサートする前に事前にそのレコードがある場合はUPdateに変更するなりすればよいと思いますが....

     

    今回は、ありがとうございました。

    2008年3月12日 1:20
  •  himi07 さんからの引用

    また、INDETITYに設定した項目が一時的に解除しているようですので、何度でも追加されますので

    INDETITYとしているフィールドには、同じ値が入ってしまいますので、注意が必要だと思います。

     

    この列にUNIQUE制約を付けてしまえば、誤って同じ値が入ることが無くなります。ただ、SQL Serverはnull同士でも同じ値だと判断してしまいますので、注意が必要です。今回のケースではnullになることが無さそうなので、大丈夫じゃないかと思いますが。

    2008年3月12日 2:12
    モデレータ
  •  

    追記ありがとうございます。

    UNIQUE制約をつけることで、良いですね。

    今回は、いろいろありがとうございました。

    2008年3月13日 5:04