0

This is just the strangest thing and I'm not sure why or what is happening. Everything runs fine in SQL Server but results in errors when ran in PHP.

In PHP, I build a dynamic statement that contains one to many queries or statements. It looks like this:

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

This morning, someone came to me because the front page to all of this was throwing errors at them. Warning: mssql_query() [function.mssql-query]: message: The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION. This code has been untouched for several months and hasn't had any problems. The code in the stored procedures probably has changed since then.

I copied the code over to SQL Server Management Studio to test and everything ran fine from a direct copy and paste. No errors, no warnings, just successful.

Next, I looked up transactions online and changed rollback to if @@trancount>0 rollback and this did fix the transaction error; however - I had a new error from 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
)

(still, a reminder: no errors are returned if I run the exact code in SQL Server Mgmt Studio)

The error involves a SP that is called at the end of each of the SP_TEST_# procedures listed in the dynamic query that PHP built. I cannot copy the SP code over to here because this is work stuff and I didn't write them so I'd really prefer to not have to paraphrase them, either, because they are huge and not formatted well. I will however, show the top of SP_TEST_RECORD where the error occurs (which isn't on line 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

So - one thing I know... some how, my PHP transaction was being ended by something in one of the stored procedures that was called by the dynamic statement and that is cause of the transaction issue. There are transactions inside of those stored procedures.

  • But why don't I see the null insert error in SQL Server when I run the same exact code? If there's a null insert, there's a null insert... so why would it make a difference if it was called from PHP or not?

  • And less importantly, how was my transaction being ended by one of the stored procedures in the beginning?

  • Why was thetransaction ended by the SP's when the code was ran in PHP but not when it was ran in SQL Server?

  • Is there some execution-concurrency-order of operations-transaction hierarchy-something going on?

4

1 回答 1

0

我不想直接删除这个问题,因为它至少对我来说是一次很棒的学习经历。但是,这是一个非常本地化的问题。前一阵子我想出了答案,所以我不记得具体的...

这肯定是因为其中一个被调用的存储过程中发生了一些事情。我很惊讶地发现错误以这种方式冒泡,尤其是在 PHP 中。我猜错误范围在其中起了一定的作用...... PHP 出现了它看到的第一个错误,但是在 SQL Server 中运行代码允许它更优雅地失败(所以我没有看到那里的错误)。不知道。故障排除...当有疑问时 - 更深入,大声笑...

于 2013-10-18T22:53:31.457 回答