Dus*_*sey 2 sql-server sql-server-2012
我有一个存储过程,在通过应用程序执行时出现以下错误:
异构查询需要为连接设置 ANSI_NULLS 和 ANSI_WARNINGS 选项。这确保了一致的查询语义。启用这些选项,然后重新发出您的查询。
该存储过程SELECT
中有一条语句连接到链接服务器表以返回结果。如果直接在SMS中执行这个存储过程,是没有任何问题的。如果我通过 ODBC 连接通过脚本执行存储过程,那么就没有问题。生成错误的唯一方法是当应用程序尝试执行它时。
查看应用程序时,没有错误。事实上,看起来运行成功,只是没有任何结果。我们能够识别此错误的唯一方法是运行 SQL 跟踪。
跟踪显示没有任何进程实际运行,相反,它只是立即出错并出现该错误。跟踪还表明它没有以不同的方式执行(例如exec sp_executesql
或类似的方式)。我可以看到存储过程开始执行,然后出现错误,然后停止。
我对此进行了大量研究,答案似乎很简单,但没有任何效果。
我尝试将SET ANSI_NULLS ON
&添加SET ANSI_WARNINGS ON
到存储过程中,甚至将其移动到其中的不同位置。但始终没能成功
另外,尝试调整数据库级别设置 -
ALTER DATABASE [NGDevl] SET ANSI_NULL_DEFAULT OFF WITH NO_WAIT
GO
ALTER DATABASE [NGDevl] SET ANSI_NULLS OFF WITH NO_WAIT
GO
ALTER DATABASE [NGDevl] SET ANSI_WARNINGS OFF WITH NO_WAIT
GO
Run Code Online (Sandbox Code Playgroud)
但即使在重新启动 SQL 实例后也不起作用。
我唯一的另一个想法是让应用程序使用其中的设置部分执行过程,就像 ---
SET ANSI_NULLS ON;SET ANSI_WARNINGS ON;exec sp_storedproc 0,0,'A','0001'
Run Code Online (Sandbox Code Playgroud)
但不幸的是,我们无法控制应用程序来尝试这一点。
此外,重新创建了存储过程,以便将链接服务器所需的所有数据提取到临时表中,使其位于本地,然后加入到那里,但出现同样的问题。
你们有什么想法或可以在这里尝试吗?该错误似乎应该很容易修复,只是不确定我错过了什么。
该问题是特定的,ANSI_WARNINGS
因为 的值ANSI_NULLS
在创建存储过程时与存储过程的定义一起存储。赶紧跑:
SELECT * FROM sys.sql_modules;
Run Code Online (Sandbox Code Playgroud)
ANSI_NULLS
要查看和之间的差异ANSI_WARNINGS
,请运行以下命令:
-- Check current values (SSMS defaults to ON for both unless changed in
-- Tools -> Options -> Query Execution -> SQL Server -> ANSI
SELECT SESSIONPROPERTY('ANSI_NULLS') AS [AnsiNulls],
SESSIONPROPERTY('ANSI_WARNINGS') AS [AnsiWarnings];
-- returns: 1 1
SET ANSI_NULLS OFF;
SET ANSI_WARNINGS OFF;
SELECT SESSIONPROPERTY(N'ANSI_NULLS') AS [AnsiNulls],
SESSIONPROPERTY(N'ANSI_WARNINGS') AS [AnsiWarnings];
-- returns: 0 0
EXEC('
CREATE PROCEDURE ##SessionSettings
AS
SELECT SESSIONPROPERTY(N''ANSI_NULLS'') AS [AnsiNulls],
SESSIONPROPERTY(N''ANSI_WARNINGS'') AS [AnsiWarnings];
');
EXEC ##SessionSettings;
-- returns: 0 0 (as expected)
SET ANSI_NULLS ON;
SELECT SESSIONPROPERTY(N'ANSI_NULLS') AS [AnsiNulls],
SESSIONPROPERTY(N'ANSI_WARNINGS') AS [AnsiWarnings];
-- returns: 1 0 (ANSI_NULLS is back ON for the session)
EXEC ##SessionSettings;
-- returns: 0 0 (ANSI_NULLS is still OFF due to being saved with the proc definition)
SET ANSI_WARNINGS ON;
SELECT SESSIONPROPERTY(N'ANSI_NULLS') AS [AnsiNulls],
SESSIONPROPERTY(N'ANSI_WARNINGS') AS [AnsiWarnings];
-- returns: 1 1 (ANSI_WARNINGS is back ON for the session)
EXEC ##SessionSettings;
-- returns: 0 1 (ANSI_WARNINGS is now ON due to NOT being saved with the proc definition)
Run Code Online (Sandbox Code Playgroud)
将SET
命令放入存储过程中为时已晚;它需要在 proc 的 EXEC 之前设置。所以你想做的事情是正确的:
SET ANSI_WARNINGS ON;exec sp_storedproc 0,0,'A','0001'
Run Code Online (Sandbox Code Playgroud)
但是,您无法更改应用程序代码及其调用过程的方式。但是,您可以更改过程本身。因此,您可以将当前过程重命名为sp_storedprocReal
并创建一个名为的新存储过程sp_storedproc
,该存储过程只是执行以下操作的包装器:
CREATE PROCEDURE sp_storedproc
(
@Param1 INT,
@Param2 INT,
@Param3 VARCHAR(50),
@Param4 VARCHAR(50)
)
AS
SET ANSI_WARNINGS ON;
EXEC sp_storedprocReal @Param1, @Param2, @Param3, @Param4;
Run Code Online (Sandbox Code Playgroud)
我在重现所述错误后测试了上面的包装程序,它确实解决了问题。
归档时间: |
|
查看次数: |
15911 次 |
最近记录: |