Sql server 显示实际查询计划是否导致错误?
好奇以前是否有人遇到过这个问题,以及根本原因是什么。问题在于,在SQL 2012中执行时,如果启用了“包含实际查询计划”,则会发生错误。无论是否有计划,它都能在2008年正常工作,在2012年也能正常工作。我在针对分区视图测试功能时发现了这一点Sql server 显示实际查询计划是否导致错误?,sql-server,tsql,Sql Server,Tsql,好奇以前是否有人遇到过这个问题,以及根本原因是什么。问题在于,在SQL 2012中执行时,如果启用了“包含实际查询计划”,则会发生错误。无论是否有计划,它都能在2008年正常工作,在2012年也能正常工作。我在针对分区视图测试功能时发现了这一点 --Setup USE master go DROP DATABASE Test GO CREATE DATABASE Test GO USE Test GO CREATE TABLE DD (pkID int IDENTITY(1,1), F
--Setup
USE master
go
DROP DATABASE Test
GO
CREATE DATABASE Test
GO
USE Test
GO
CREATE TABLE DD (pkID int IDENTITY(1,1), FullDate date);
INSERT INTO DD (FullDate) VALUES ('2013-01-01')
INSERT INTO DD (FullDate) VALUES ('2013-01-02')
INSERT INTO DD (FullDate) VALUES ('2013-01-03')
INSERT INTO DD (FullDate) VALUES ('2013-01-04')
INSERT INTO DD (FullDate) VALUES ('2013-01-05')
GO
CREATE TABLE DC (pkID int IDENTITY(1,1), Filter varchar(32), FilterGroup varchar(32));
INSERT INTO DC (Filter, FilterGroup) VALUES ('one', 'groupone')
INSERT INTO DC (Filter, FilterGroup) VALUES ('two', 'grouptwo')
INSERT INTO DC (Filter, FilterGroup) VALUES ('three', 'groupone')
GO
CREATE TABLE FDA1 (pkID int IDENTITY(1,1), fkpID int, fkCID int, fkDateID int)
INSERT INTO FDA1(fkpID, fkCID, fkDateID) VALUES (1,1,1)
INSERT INTO FDA1(fkpID, fkCID, fkDateID) VALUES (1,2,1)
INSERT INTO FDA1(fkpID, fkCID, fkDateID) VALUES (1,1,3)
INSERT INTO FDA1(fkpID, fkCID, fkDateID) VALUES (1,3,5)
GO
CREATE TABLE FDA2 (pkID int IDENTITY(1,1), fkpID int, fkCID int, fkDateID int)
INSERT INTO FDA2(fkpID, fkCID, fkDateID) VALUES (2,1,2)
INSERT INTO FDA2(fkpID, fkCID, fkDateID) VALUES (2,2,2)
INSERT INTO FDA2(fkpID, fkCID, fkDateID) VALUES (2,1,4)
INSERT INTO FDA2(fkpID, fkCID, fkDateID) VALUES (2,3,5)
GO
CREATE VIEW FDA
AS
SELECT pkID, fkpID, fkCID, fkDateID FROM FDA1
UNION ALL
SELECT pkID, fkpID, fkCID, fkDateID FROM FDA2
GO
CREATE FUNCTION GetFilter
(
@pID int
, @filterGroup varchar(32)
)
RETURNS @Filter TABLE
(
CID int
)
AS
BEGIN
INSERT INTO
@Filter
SELECT
dc.pkID
FROM
DC dc
WHERE
dc.FilterGroup = @filterGroup
RETURN
END
GO
CREATE PROC test (@ID int)
AS
BEGIN
BEGIN TRY
DECLARE @FilterGroup varchar(32) = 'groupone'
SELECT
CAST(MIN(dd.FullDate) As datetime) as ProjectReviewStartDate
FROM
dbo.FDA fda
INNER JOIN dbo.DD dd On fda.fkDateID = dd.pkID
INNER JOIN dbo.GetFilter(@ID, @FilterGroup) ctl on fda.fkCID = ctl.CID
WHERE
fda.pkID = @ID
OPTION (RECOMPILE);
RETURN 0;
END TRY
BEGIN CATCH
--Declare variables for error information.
Declare
@ErrorMessage nvarchar(max),
@ErrorSeverity bigint,
@ErrorState int;
--Populate error information.
Select
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
--Re-throw error to calling method.
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
--Failure
RETURN -1;
END CATCH;
END
GO
现在安装完成了,让我们运行实际代码,首先“包括实际执行计划”
您应该会收到以下结果:2013-01-01 00:00:00.000
现在启用“包含实际执行计划”,您将收到NULL的结果并看到一个错误(在SQL 2012中):
Msg 50000,16级,状态10,程序测试,第33行
字符串或二进制数据将被截断
启用Include Actual Execution Plan并从进程中删除Try/Catch块时,将删除错误并返回正确的结果。然而,在2008年,这种方法同样适用
有什么想法吗
谢谢我还没有答案给你,只是你可能遇到了一个bug 首先,为了证明这不涉及
RAISERROR
,具体来说,将该行更改为:
THROW;
返回此错误消息:
Msg 8152,16级,状态10,程序测试,第7行字符串或二进制数据将被截断 这表明错误发生在
SELECT
调用中,与TRY/CATCH
和show实际计划的组合有关
接下来,让我们看看元数据将什么描述为存储过程的输出:
SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set_for_object
(OBJECT_ID('test'), NULL);
结果:
name system_type_name
---------------------- ----------------
ProjectReviewStartDate datetime
现在,如果我们尝试测试正在运行的批处理的元数据,那么让我们看看它对元数据的说明(实际上,结果是一条错误消息):
SELECT [error_message]
FROM sys.dm_exec_describe_first_result_set(N'DECLARE @id int = 1
DECLARE @tbl table (dt datetime)
DECLARE @findate datetime
INSERT @tbl
EXEC test @id', -1, NULL);
结果是:
error_message
----------------------------------------------------------
Incorrect syntax near '-'.
The batch could not be analyzed because of compile errors.
批处理中没有-
。这是在执行计划关闭的情况下。即使在上面的批处理中注释掉了insert,也会得到相同的结果。例如:
SELECT error_message
FROM sys.dm_exec_describe_first_result_set(N'EXEC test 1', -1, NULL);
错误消息的变化非常轻微(仔细观察):
我们已经消除了showplan的任何参与或潜在的截断,我们仍然可以证明SQL Server在为这个简单的批处理编译和/或生成元数据时存在某种问题
这似乎是一个相当简单的重做,你有变通办法,但
编辑
我看到你已经提交了一个bug;任何其他可以重新编程的人都应投票确认重新编程:
SELECT error_message
FROM sys.dm_exec_describe_first_result_set(N'EXEC test 1', -1, NULL);
error_message
----------------------------------------------------------
Incorrect syntax near '1'.
The batch could not be analyzed because of compile errors.