使用PHP运行使用SQL Server中存储的过程和事务的查询会导致神秘的错误
这是最奇怪的事情,我不知道为什么或者发生了什么。在SQL Server中运行一切正常,但在PHP中运行时会导致错误 在PHP中,我构建了一个包含一对多查询或语句的动态语句。看起来是这样的:使用PHP运行使用SQL Server中存储的过程和事务的查询会导致神秘的错误,php,sql,sql-server,error-handling,transactions,Php,Sql,Sql Server,Error Handling,Transactions,这是最奇怪的事情,我不知道为什么或者发生了什么。在SQL Server中运行一切正常,但在PHP中运行时会导致错误 在PHP中,我构建了一个包含一对多查询或语句的动态语句。看起来是这样的: begin try begin transaction -- statement 1 UPDATE table_name SET status = 1 WHERE things='stuff'; -- dynamic: to run after inserts
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
今天早上,有人来找我,因为所有这些的头版都在向他们抛出错误<代码>警告:mssql_query()[function.mssql query]:消息:回滚事务请求没有相应的BEGIN事务。此代码已几个月未被触及,并且没有任何问题。此后,存储过程中的代码可能已更改
我将代码复制到SQLServerManagementStudio进行测试,通过直接复制和粘贴,一切正常。没有错误,没有警告,只是成功了
接下来,我在线查找事务,并将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
)
(不过,提醒一下:如果我在SQLServerMgmtStudio中运行完全相同的代码,则不会返回任何错误)
该错误涉及在PHP构建的动态查询中列出的每个SP_TEST#
过程结束时调用的SP我无法将SP代码复制到此处,因为这是工作资料,我没有编写它们,所以我也不想对它们进行解释,因为它们太大,格式不好。但是,我将显示出现错误的SP_TEST_记录的顶部(不在第247行):
所以-有一件事我知道。。。我的PHP事务是如何被动态语句调用的某个存储过程中的某个东西结束的,这就是事务问题的原因。这些存储过程中有事务
- 但是当我运行相同的代码时,为什么在SQL Server中看不到空插入错误?如果有空插入,则有空插入。。。那么,如果它是从PHP调用的,为什么会有不同呢
- 更不重要的是,一开始我的事务是如何被一个存储过程结束的
- 为什么当代码在PHP中运行时,而不是在SQL Server中运行时,转换被SP终止
- 是否存在操作事务层次结构的某些执行并发顺序
我不想直接删除这个问题,因为它至少对我来说是一次很好的学习经历。然而,这是一个非常本地化的问题。我前一阵子就知道答案了,所以我记不起具体的细节
这肯定是因为在一个被调用的存储过程中发生了一些事情。我很惊讶地发现错误是这样冒出来的,尤其是在PHP中。我猜误差范围在其中起了一定作用。。。PHP接受了它看到的第一个错误,但在SQL server中运行代码使其更容易失败(因此我没有看到错误)。不知道故障排除。。。当有疑问的时候-更深一点,哈哈
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