以后出现错误时,看不到预期的 PRINT 或 RAISERROR 输出
Posted
技术标签:
【中文标题】以后出现错误时,看不到预期的 PRINT 或 RAISERROR 输出【英文标题】:Cannot see expected PRINT or RAISERROR output when a later error is raised 【发布时间】:2020-06-02 02:38:48 【问题描述】:我在存储过程中收到一条错误消息,说我无法将 NULL 值插入表中,而如果值为 null,我应该在代码中更早的时候收到错误。
这是存储过程的相关部分:
CREATE PROCEDURE [dbo].[udp_AddUpdateStaffVariable]
-- Add the parameters for the stored procedure here
@StaffID int=null,
@VariableTypeID int,
@VariableIntValue int=null,
@VariableVarcharValue varchar(max)=null,
@VariableDatetimeValue datetime=null,
@VariableDecimalValue decimal=null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
BEGIN TRY
DECLARE @PrintOutput varchar(150)
SET @PrintOutput = '@StaffID = ' + CASE WHEN @StaffID = NULL THEN 'Null' ELSE CONVERT(varchar(20), @StaffID) END
RAISERROR (@PrintOutput, 10, 1) WITH NOWAIT
IF (@StaffID = NULL) -- If the staffid of the current user was not supplied, find it in the Staff table
BEGIN
DECLARE @CurrentUser nvarchar(255) = SUSER_SNAME();
SELECT @StaffID = [StaffID] FROM [dbo].[Staff] WHERE [UserName] = @CurrentUser;
SET @PrintOutput = '@StaffID = ' + CASE WHEN @StaffID = NULL THEN 'Null' ELSE CONVERT(varchar(20), @StaffID) END
RAISERROR (@PrintOutput, 10, 1) WITH NOWAIT
IF @StaffID = NULL -- raise error if staffid wasn't found
BEGIN
RAISERROR (50001 --error number
, 16 -- severity
, 1 --state
, @CurrentUser -- parameter
)
END
END
-- Get the variable data type (used to determine where the variable is stored)
DECLARE @VarDataTypeDesc varchar(20)
DECLARE @StaffVarID int
SELECT @VarDataTypeDesc = dt.[StaffVariableDataType]
FROM [list].[DataTypes] dt INNER JOIN [list].[StaffVariableTypes] svt ON dt.DataTypeID = svt.DataTypeID
WHERE svt.VariableTypeID = @VariableTypeID
-- update or add the staff variable
IF EXISTS (SELECT 1 FROM [dbo].[StaffVariables] WHERE StaffID = @StaffID AND [VariableTypeID] = @VariableTypeID) -- update
BEGIN
IF @VarDataTypeDesc = 'int'
BEGIN -- only update here - other data types are updated further down
UPDATE [dbo].[StaffVariables] SET VariableIntValue = @VariableIntValue WHERE StaffID = @StaffID AND VariableTypeID = @VariableTypeID
END
ELSE -- StaffVariableID is only needed if the variable type is not int
BEGIN
SELECT @StaffVarID = StaffVariableID FROM [dbo].[StaffVariables] WHERE StaffID = @StaffID AND [VariableTypeID] = @VariableTypeID
END
END
ELSE -- insert
BEGIN
IF @VarDataTypeDesc = 'int'
BEGIN
INSERT INTO [dbo].[StaffVariables] (StaffID, VariableTypeID, VariableIntValue)
VALUES (@StaffID, @VariableTypeID, @VariableIntValue)
END
ELSE -- StaffVariableID is only needed if the variable type is not int
BEGIN
DECLARE @StaffVarIDTbl table(ID int)
INSERT INTO [dbo].[StaffVariables] (StaffID, VariableTypeID, VariableIntValue)
OUTPUT INSERTED.[StaffVariableID] INTO @StaffVarIDTbl
VALUES (@StaffID, @VariableTypeID, @VariableIntValue)
SELECT @StaffVarID = ID FROM @StaffVarIDTbl
END
END
-- Cutting out the section where I deal with other variable types besides int here - not relevant to this problem
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
END CATCH;
END
这是测试程序运行代码:
DECLARE @return_value int
EXEC @return_value = [dbo].[udp_AddUpdateStaffVariable]
@VariableTypeID = 1,
@VariableIntValue = 10
SELECT 'Return Value' = @return_value
GO
...这是回复:
Msg 50000, Level 16, State 2, Procedure dbo.udp_AddUpdateStaffVariable, Line 130 [Batch Start Line 2]
Cannot insert the value NULL into column 'StaffID', table 'SnippingDbName.dbo.StaffVariables'; column does not allow nulls. INSERT fails.
(1 row affected)
Completion time: 2020-06-01T21:17:08.2049072-05:00
所以...这是问题所在。该错误似乎表明它要么从未运行过整个代码,if @StaffID = NULL
部分,要么确实运行了,但没有找到 StaffID
并设置了 @StaffID
变量。但如果是这样的话,为什么我看不到我之前的RAISERROR
语句的结果?
我最初尝试 PRINT 并在 PRINT
不起作用时切换到 RAISERROR
。
SQL Server 2017 开发者版,SSMS 15.0.18183.0
【问题讨论】:
这不会是您的错误,但您应该保持一致并使用throw
将错误信息返回给应用程序。 raiserror
是老式风格。
我绝不是编码大师,但我认为你的IF ( @StaffId = NULL )
应该是IF ( @StaffId IS NULL )
。我认为您的员工 ID 永远不能等于 NULL,它只能是 NULL(如果这有意义的话)。同样,就在您的 RAISERROR 语句之前。
^^^ 他们所说的......你使用IS
而不是=
与null进行比较
糟糕!是的,将“= NULL”修复为“IS NULL”消除了所有错误。 :) 现在运行一个快速测试,看看如果在 Staff 表中找不到当前用户会发生什么...
耶!有效! :) 谢谢大家。
【参考方案1】:
评论问题的人发现这是一个语法错误。 IF (@StaffID = NULL)
应该是,IF (@StaffID IS NULL)
在过程中的所有位置修复该问题,并更改我的测试人员记录,使用户名与 SUSER_SNAME()
不匹配导致预期的错误。
【讨论】:
请将此标记为答案,以便将来对人们有所帮助 我会的,但实际上我对这一切仍有一些不明白的地方(在我刚刚在原始问题下发表的评论中)。以上是关于以后出现错误时,看不到预期的 PRINT 或 RAISERROR 输出的主要内容,如果未能解决你的问题,请参考以下文章
在 Ubuntu 14.04 和 matlab 2014Ra 上使用犰狳在 mex 中出现分段错误
为啥会出现“svn: E120106: ra_serf: The server sent a truncated HTTP response body”错误? [复制]