これは最も奇妙なことであり、なぜ、または何が起こっているのかわかりません。SQL Server ではすべて正常に動作しますが、PHP で実行するとエラーが発生します。
PHP では、1 対多のクエリまたはステートメントを含む動的ステートメントを作成します。次のようになります。
begin try
begin transaction
-- statement 1
UPDATE table_name SET status = 1 WHERE things='stuff';
-- dynamic: to run after inserts
exec [dbo].[SP_TEST_2];
exec [dbo].[SP_TEST_3];
exec [dbo].[SP_TEST_9];
exec [dbo].[SP_TEST_14];
commit
select 'successful' as for_php_success_message
end try
begin catch
rollback
select error_number() as for_php_error_number
,error_severity() as for_php_error_severity
,error_state() as for_php_error_state
,error_procedure() as for_php_error_procedure
,error_line() as for_php_error_line
,error_message() as for_php_error_message;
end catch
今朝、誰かが私のところに来ました。なぜなら、これらすべてのトップページが彼らにエラーを投げかけているからです。 Warning: mssql_query() [function.mssql-query]: message: The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
このコードは数か月間変更されておらず、何の問題もありません。ストアド プロシージャのコードは、おそらくそれ以降変更されています。
コードを SQL Server Management Studio にコピーしてテストしたところ、直接コピーして貼り付けるだけですべて正常に動作しました。エラーも警告もなく、ただ成功しました。
次に、オンラインでトランザクションを調べて変更rollback
するif @@trancount>0 rollback
と、トランザクション エラーが修正されました。ただし、PHP から新しいエラーが発生しました。
Array
(
[for_php_error_number] => 50000
[for_php_error_severity] => 16
[for_php_error_state] => 1
[for_php_error_procedure] => SP_TEST_Record
[for_php_error_line] => 247
[for_php_error_message] => spTEST_Record: 515: Cannot insert the value NULL into column 'TEST_DATA', table 'tempdb.dbo.#IDs________________________________________________________________________________________________________________00000001D27E'; column does not allow nulls. INS
)
(なお、注意: SQL Server Mgmt Studio で正確なコードを実行してもエラーは返されません)
SP_TEST_#
このエラーには、 PHP が作成した動的クエリにリストされている 各プロシージャの最後に呼び出される SP が含まれます。SP コードをここにコピーすることはできません。これは仕事用のものであり、私が書いたものではないため、言い換える必要がないことを本当に望んでいます。SP_TEST_RECORD
ただし、エラーが発生した場所の上部を表示します (247 行目ではありません)。
ALTER PROCEDURE [dbo].[SP_TEST_Record] (
@Test_ID real=0, @debug int=1, @create_entry int=0, @autoclose bit=0, @autodelete bit=0
)
AS
BEGIN
SET NOCOUNT ON;
declare @vtest_id real; set @vtest_id=@Test_ID
declare @vdebug int; set @vdebug=@debug
declare @vcreate_entry bit; set @vcreate_entry=@create_entry
declare @vautoclose bit; set @vautoclose=@autoclose
declare @vautodelete bit; set @vautodelete=@autodelete
declare @test_date datetime; set @test_date=getutcdate()
declare @ct int;
begin try
begin tran
if object_id('tempdb..#IDs') is not null drop table #IDs
CREATE TABLE #IDs (TYC_ID int not null, TYC_TYPE_ID int not null, TYC_ENV_ID int not null, TEST_DATA nvarchar(2000) null) ON [PRIMARY]
ALTER TABLE #IDs ADD PRIMARY KEY NONCLUSTERED (TYC_ID, TYC_TYPE_ID, TYC_ENV_ID)
insert into #IDs(TYC_ID, TYC_TYPE_ID, TYC_ENV_ID, TEST_DATA)
select TYC_ID, TYC_TYPE_ID, TYC_ENV_ID, TEST_DATA from SR_TESTING where TEST_ID=@vTest_ID
だから - 私が知っていることの1つ...どういうわけか、私のPHPトランザクションは、動的ステートメントによって呼び出されたストアドプロシージャの1つで何かによって終了されており、それがトランザクションの問題の原因です。これらのストアド プロシージャ内にはトランザクションがあります。
しかし、まったく同じコードを実行しても、SQL Server で null 挿入エラーが表示されないのはなぜですか? null挿入がある場合、null挿入があります...では、PHPから呼び出されたかどうかにかかわらず、なぜ違いが生じるのでしょうか?
それほど重要ではありませんが、トランザクションが最初にストアド プロシージャの 1 つによってどのように終了されたのでしょうか。
コードが PHP で実行されたときに SP によってトランザクションが終了されたのに、SQL Server で実行されたときにはトランザクションが終了しなかったのはなぜですか?
操作の実行 - 並行性 - 順序 - トランザクション階層 - 何かが起こっていますか?