4

更新された質問

したがって、この問題をさらにデバッグしたところ、コードは次のようになりました。

$mssql->beginTransaction();
$mssql->sql("DELETE FROM [TABLE] WHERE [FIELD] = 'Test'");
// Write the result from the above query,
// this will confirm the row was deleted
print_r($mssql->result);

$mssql->sql("SELECT FROM [TABLE] WHERE [FIELD] = 'Test'");
// Write the result from the above query,
// this SHOULD be empty as the row was just deleted
print_r($mssql->result);
$mssql->endTransaction();

上記のスクリプトは、ある SQL Server データベースでは完全に機能しますが、別のデータベース (別のサーバー上の複製データベース) では機能しません。

2番目のデータベースは、行が削除されたはずなのに、テーブルから行を取得することに成功しています...

追加情報

  1. 私が見る限り、データベース オプションの唯一の違いは、Broker Enabledこれとは関係がないと思われるオプションです。
  2. 取引オプションへのアクセス方法や表示方法がわかりません。これらは関係ありますか?
  3. これはテーブルのロックに関係しているのでしょうか?

SQL トレース

declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,N'@P1 nvarchar(6)',N'DELETE FROM TABLE WHERE [FIELD]=@P1',N'M87996'
select @p1
go
declare @p1 int
set @p1=2
exec sp_prepexec @p1 output,NULL,N'SELECT db_name()'
select @p1
go
exec sp_unprepare 2
go
exec sp_unprepare 1
go
declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,N'@P1 nvarchar(6)',N'SELECT * FROM [TABLE] WHERE [FIELD]=@P1 ',N'M87996'
select @p1
go
exec sp_unprepare 1
go

元の質問

SQL トランザクションを扱うのはこれが初めてなので、無知でしたら申し訳ありません。

データベースから項目を削除し、更新された項目を同じ主キーの下に挿入するトランザクションがあります。

次のことを考慮してください (私のラッパー クラス関数は無視してください)。

$mssql->beginTransaction();
$mssql->sql("DELETE FROM [TABLE] WHERE [FIELD] = 'Test'");
$mssql->sql("INSERT INTO [TABLE] ([FIELD]) VALUES ('Test'));
$mssql->endTransaction();

ただし、上記の場合、Duplicate Primary Keyエラーが発生します。それは最初のクエリをコミットしていないからですか?

したがって、同じトランザクションで上記の両方のクエリを実行することはできませんか?

残念ながら、いくつかの行を削除する必要があり、削除する行を知る方法がないため、単純な UPDATE コマンドで上記を実行することはできません...

4

1 に答える 1

3

いいえ、それは別の何かが働いているに違いありません。コミットする必要はありません。同じトランザクション内で常に独自の変更が表示されるため、INSERT を開始するまでに DELETE は既に完了しています。

最初に検証する必要があると思うのは、DELETE が実際に行を削除することです。WHERE 句との照合に暗黙のうちに失敗する可能性があります (つまり、0 行が削除され、 の戻り値を確認してくださいPDO::exec)。これは、VARCHAR と NVARCHAR (Ascii と Unicode) を組み合わせた照合の問題によって説明できます。推測するのは難しいです。

于 2013-06-20T19:13:37.773 に答える