从PHP执行时SQL Server查询不起作用

时间:2016-08-25 14:54:26

标签: php sql-server triggers sql-server-2012 sqlsrv

我在triggers的表格中有一组SQL Server,当我在SQL Server Management Studio执行查询时,它们运行正常。但是当他们从我的php文件中执行时,他们并没有生效。我使用SQL Server Profiler并且触发器到达我的日志表中插入的最后一行执行但在此之后我得到Attention错误。这是我删除声明的触发器:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- Batch submitted through debugger: SQLQuery25.sql|7|0|C:\Users\ADMINI~1\AppData\Local\Temp\3\~vsB4EE.sql

ALTER TRIGGER [dbo].[OperationStructureFields_delete]
ON [dbo].[OperationStructureFields]
FOR DELETE
AS
BEGIN
    DECLARE
        @id INT,
        @result varchar(MAX),
        @user varchar(MAX),
        @LoopCounter INT = 1, 
        @MAX INT, 
        @Column NVARCHAR(100),
        @Type NVARCHAR(100),
        @Value NVARCHAR(100),
        @ValueXML xml,
        @Sql NVARCHAR(MAX),
        @Tmp NVARCHAR(MAX),
        @LoopCounter2 INT = 1,
        @MAX2 INT,
        @Message nvarchar(2048)
    SELECT @user = system_user
    SELECT @MAX = MAX(ORDINAL_POSITION) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'OperationStructureFields'
    SELECT @MAX2 = MAX(ID) FROM deleted
    SELECT @LoopCounter2 = MIN(ID) FROM deleted
    Select * into #deleted from deleted
    WHILE(@LoopCounter2 <= @MAX2)
    BEGIN
        SET @LoopCounter = 1
        SET @result = '{'
        WHILE(@LoopCounter <= @MAX)
        BEGIN
           SELECT @Column = COLUMN_NAME, @Type = DATA_TYPE
           FROM INFORMATION_SCHEMA.COLUMNS WHERE ORDINAL_POSITION = @LoopCounter and TABLE_NAME = 'OperationStructureFields'
           if (@Type = 'xml')
           BEGIN
            SET @Sql = 'SELECT @ValueXML = ' + @Column + ' FROM #deleted where ID=' + CONVERT(varchar(200),@LoopCounter2,0)
            exec sp_executesql @Sql, N'@ValueXML xml out', @ValueXML out
            SET @Value = CONVERT(VARCHAR(MAX),@ValueXML,0)
           END
           ELSE
           BEGIN
             SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #deleted where ID=' + CONVERT(varchar(200),@LoopCounter2,0)
             exec sp_executesql @Sql, N'@Value varchar(MAX) out', @Value out 
           END    
           IF (@Value is not null or @Value != '') and  (@Type = 'datetime2' or @Type = 'datetime' or @Type = 'date')
           BEGIN
                IF @result = '{'
                BEGIN
                    SET @result = @result + ' "' + @Column + '":"' + CONVERT(VARCHAR(20),@Value,120) + '"'
                END
                ELSE
                BEGIN
                    SET @result = @result + ', "' + @Column + '":"' + CONVERT(VARCHAR(20),@Value,120) + '"'
                END
           END
           ELSE IF (@Value is not null or @Value != '')
           BEGIN
                IF @result = '{'
                BEGIN
                    SET @result = @result + ' "' + @Column + '":"' + @Value + '"'
                END
                ELSE
                BEGIN
                    SET @result = @result + ', "' + @Column + '":"' + @Value + '"'
                END
           END
           SET @LoopCounter  = @LoopCounter + 1 
        END
        SET @result = @result + '}'
        INSERT INTO sys_logs (username,datahora,tabela,[object_id],[action],oldvalue) values (@user,GETDATE(),'OperationStructureFields',@LoopCounter2,'DELETE',@result)
        delete from #deleted where ID = @LoopCounter2
        select @LoopCounter2 = MIN(ID) from #deleted where ID > @LoopCounter2  
    END
END

我的SQL Server Profiler的打印:

Prt Screen do SQL Server Profiler

PHP代码是:

$res = sqlsrv_query($connection, $_sql, array(), array('Scrollable' => 'buffered'));

并且变量$_sql具有以下值:

DELETE FROM OperationStructureFields WHERE ID= '66817'

并且它不会返回任何错误。

PHP版本为5.5.16

我在我的php文件中执行了SELECT @@OPTIONS并获得了以下选项:

ANSI_WARNINGS
ANSI_PADDING
ANSI_NULLS
QUOTED_IDENTIFIER
ANSI_NULL_DFLT_ON
CONCAT_NULL_YIELDS_NULL

与SQL Server Management Studio的唯一区别是SQL Server Management Studio中的ARITHABORT选项。

你有什么想法可能导致这个吗?

更新

我相信它可能是我的PHP设置上的内容。在ONphpinfo()获得了以下设置:

phpinfo();

同样在sqlsrv我已在SQL Server Profiler中获得以下定义:

Audit Login

2 个答案:

答案 0 :(得分:1)

消息

  

将数据库上下文更改为XXXXXXX

     

将语言设置更改为YYYYYYY

不是错误消息。它们是信息性消息,应该被应用程序忽略。 PHP可以配置为忽略它。

严重级别:https://msdn.microsoft.com/en-us/library/ms164086.aspx

PHP设置:

1)php.ini更改:

mssql.min_error_severity = 11
mssql.min_message_severity = 11

2)执行

mssql_min_error_severity(11);

在执行mssql_query()

之前

http://php.net/manual/en/function.mssql-min-error-severity.php

更新:

3)触发器应该

set nocount on;

位于代码顶部,紧跟在:

之后
AS
BEGIN

这样可以防止向应用程序发送多条信息性消息(例如&#34; xx行受影响&#34;)。

答案 1 :(得分:0)

每个应用程序SQL驱动程序(包括SSMS)都有标准的SET选项。这些可以被覆盖,但默认情况下,驱动程序将传递某些设置值。 (如果您不知道我在说什么,请查看this article以了解选项是什么,并找出如何确定使用哪些选项。

我建议的是确定您的应用程序使用的SET选项,然后模仿SSMS中的那些,然后从那里进行故障排除。您的另一个选择是继续执行应用程序中的set语句,以与SSMS的默认值保持一致。我们在Node.js应用程序中做了类似的事情几年,因为我们从.Net中运行良好的procs返回了一些错误。一旦我们在Node中添加语句到parrot .Net一切正常。

我不肯定你的问题是由于SET选项,但我认为很可能。