SQLの一括挿入によるトランザクションでは削除できません

ado.net c# sqlbulkcopy sql-server-2008 transactions

質問

私はテーブルからいくつかのレコードを削除し、いくつかのレコードを同じテーブルに挿入する必要があります。この削除および挿入プロセスはトランザクション内にある必要があります。

以下は私がしたことです。

 using (SqlConnection sqlConn = new SqlConnection(connectionString))
        {
            sqlConn.Open();
            using (SqlTransaction sqlTran = sqlConn.BeginTransaction())
            {
                string deleteQuery = "delete from dbo.MyTable where Col1 =" + colValue;
                SqlCommand sqlComm = new SqlCommand(deleteQuery, sqlConn,sqlTran);
                sqlComm.ExecuteNonQuery();
                using (SqlBulkCopy sqlcopy = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.Default, sqlTran))
                {
                    sqlcopy.BatchSize = 10;
                    sqlcopy.DestinationTableName = "MyTable";
                    try
                    {
                        sqlcopy.WriteToServer(dsDataSet.Tables[0]);
                        sqlTran.Commit();
                    }
                    catch (Exception ex)
                    {
                        sqlTran.Rollback();
                    }
                }
            }
        }

しかし、私は削除操作が挿入前に実行されていないと思う、私は重複キーエラーを取得します。誰かが助けることができますか?

受け入れられた回答

私はあなたのサンプルコードを試して、それは私のために働くように見えました。重複した挿入がエラーを投げるかどうかを確認するために、列の1つにPKを作成しました。次に、コードを2回実行します。最初にダミーデータを挿入し(エラーはスローされません)、2回目にデータを削除してから同じトランザクション内に挿入します。あなたの質問から、私は2回目の例外を得ることを望んでいたが、それはうまくいった。それは問題ではありませんが、SQL Server 2008 R2 SP1を実行しています。

ここに私が使用した完全なテストコードがあります。あなたの問題を特定するのに役立つでしょう。

最初にサンプルテーブルを作成するためのSQL:

CREATE TABLE [dbo].[MyTable](
    [Col1] [nvarchar](20) NOT NULL,
    [Col2] [nvarchar](20) NULL,
    [Col3] [nvarchar](30) NULL,
    CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
    (
        [Col1] ASC
    )
)

そしてC#:

public static void Main()
{
    DataTable t = new DataTable();
    t.Columns.Add(new DataColumn("Col1"));
    t.Columns.Add(new DataColumn("Col2"));
    t.Columns.Add(new DataColumn("Col3"));
    for (int i = 0; i < 5; i++)
    {
        var r1 = t.NewRow();
        r1["Col1"] = "1" + i.ToString();
        r1["Col2"] = "2" + i.ToString();
        r1["Col3"] = "3" + i.ToString();
        t.Rows.Add(r1);
    }
    t.AcceptChanges();
    var connectionString = new SqlConnectionStringBuilder();
    connectionString.DataSource = "localhost";
    connectionString.InitialCatalog = "testdb";
    connectionString.IntegratedSecurity = true;

    using (SqlConnection sqlConn = new SqlConnection(connectionString.ToString()))
    {
        sqlConn.Open();
        using (SqlTransaction sqlTran = sqlConn.BeginTransaction())
        {
            string deleteQuery = "delete from MyTable"; // just delete them all
            SqlCommand sqlComm = new SqlCommand(deleteQuery, sqlConn, sqlTran);
            sqlComm.ExecuteNonQuery();
            using (SqlBulkCopy sqlcopy = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.Default, sqlTran))
            {
                sqlcopy.BatchSize = 10;
                sqlcopy.DestinationTableName = "MyTable"; 
                try
                {
                    sqlcopy.WriteToServer(t);
                    sqlTran.Commit();
                }
                catch (Exception ex)
                {
                    sqlTran.Rollback();
                }
            }
        }
    }

}

あなたの質問に更新さて、 2011年11月23日が数式として評価されたため( '/'は除算)、値0が返され、暗黙的にdatetimeにキャストされていたため、エラーは発生しませんでした。 1900/01/01。クエリ "select CONVERT(datetime、11/23/2011)"を実行してみると、私の意味がわかります。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ