0

これは最も奇妙なことであり、なぜ、または何が起こっているのかわかりません。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 で実行されたときにはトランザクションが終了しなかったのはなぜですか?

  • 操作の実行 - 並行性 - 順序 - トランザクション階層 - 何かが起こっていますか?

4

1 に答える 1

0

少なくとも私にとっては素晴らしい学習体験だったので、この質問をそのまま削除したくはありませんでした。しかし、それは非常に局所的な質問でした。少し前に答えを見つけたので、詳細を思い出せません...

これは間違いなく、後で呼び出されたストアド プロシージャの 1 つで何かが発生したために発生しました。エラーがそのように発生したことを知って、特に PHP で非常に驚きました。私は、エラースコープがその役割を果たしたと思います... PHPは最初に見たエラーを受け取りましたが、SQLサーバーでコードを実行すると、より適切に失敗することができました(そのため、エラーは表示されませんでした)。わからない。トラブルシューティング...疑わしい場合は、さらに深く掘り下げてください(笑)...

于 2013-10-18T22:53:31.457 に答える