我在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的打印:
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设置上的内容。在ON
我phpinfo()
获得了以下设置:
同样在sqlsrv
我已在SQL Server Profiler
中获得以下定义:
Audit Login
答案 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选项,但我认为很可能。