我应该如何转义%
参数中的字符,以便我重新调整RAISERROR
我的消息
declare @msg varchar(max) = (SELECT ' Message with % ' AS MSG)
if @msg is not null
begin
RAISERROR (@msg ,16,1);
end
Run Code Online (Sandbox Code Playgroud)
这将引发错误消息
消息 2787,级别 16,状态 1,第 4 行
无效的格式规范:“%”。
对于最终用户,此消息是不可读的。
我的消息是从数据库生成并设置此消息。
我避免收到错误消息的方法是替换
set @msg = REPLACE(@msg,'%','P')
Run Code Online (Sandbox Code Playgroud)
但是我还是不知道怎么加%
符号
我需要有条件地引发错误,但我只能使用简单的语句,而不能使用存储过程。
我想做这样的事情:
select case when foo = "bar" then 1 else SIGNAL SQLSTATE 'ERROR' end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,SIGNAL 仅可用于触发器和过程,我必须在现有应用程序中使用它,该应用程序只允许我输入语句,但不允许我输入过程。(我只有一条长线,无法设置分隔符等)
有没有其他方法可以有条件地导致运行时错误?
我希望在抛出自定义错误消息时通知操作员。我的理解是我需要向 sys.messages 添加一条消息,然后我可以RAISERROR
或者THROW
那个错误 ID。在消息 ID 上创建警报并将其设置为发送给操作员应该会创建这些通知。
我在消息 ID 50005 上创建了 SQL 代理警报,并使用以下 T-SQL 创建消息:
EXEC sp_addmessage @msgnum = 50005,
@severity = 16,
@msgtext = N'%s';
GO
Run Code Online (Sandbox Code Playgroud)
然后,如果我执行这个:
RAISERROR (50005, -- Message id.
16, -- Severity,
1, -- State,
N'My custom message');
THROW 50005, 'My custom message', 1;
GO
Run Code Online (Sandbox Code Playgroud)
我从RAISERROR
和得到以下输出THROW
:
Msg 50005, Level 16, State 1, Line 68 我的自定义消息
但是,当我查看警报的历史记录时,它显示它尚未触发,并且操作员未收到电子邮件更新。
我的代理警报如下所示:
编写警报脚本会生成以下内容:
USE [msdb]
GO
EXEC msdb.dbo.sp_update_alert @name=N'Alert DBA on custom errors',
@message_id=50005, …
Run Code Online (Sandbox Code Playgroud) 我可以轻松地在严重性不高于 18 的情况下引发用户定义的错误。当更高时,我收到此错误
大于 18 的错误严重级别只能由 sysadmin 角色的成员使用 WITH LOG 选项指定。
我有权访问 sysadmin 角色,所以有人可以指定使用 LOG 选项引发错误的语法。谢谢。
在我看来,SQL THROW 缺少一个重要的功能,那就是当错误号记录在应用程序日志中时可以触发警报的RAISERROR
能力。WITH LOG
有没有一种简单的方法可以做到这一点,但我却无法做到这一点,还是我仍然必须依赖更麻烦的RAISERROR
SP sp_addmessage
?
我希望能够通过THROW
在块中使用的警报来通知操作员CATCH
。
我刚刚遇到了 SQL 的一部分,它的行为与我预期的不同(请参阅下面的有关 SQL 的提炼版本,该版本演示了问题模式)。
(这是在 SQL Server 2008 R2 SP2 64 位上)
“在这里做一些工作”部分会引发错误并触发 CATCH 块中的错误处理。错误编号为 515(尝试将空值插入不可为空的列),因此 RAISERROR 报告错误,但随后循环继续,再次尝试工作,在无限循环中引发错误等。
我希望 RAISERROR 导致执行退出循环。这里发生了什么?
谢谢
WHILE (@Applied <> 1)
BEGIN
BEGIN TRY
-- === Do some work here ===
-- Successfully applied
SET @Applied = 1;
END TRY
BEGIN CATCH
-- Save the error details
SELECT
@ErrorNumber = ERROR_NUMBER(),
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
-- Test for a deadlock or uncommittable transaction
IF (@ErrorNumber = 1205 OR @ErrorNumber …
Run Code Online (Sandbox Code Playgroud) 我的错误级别 16 警报设置如下:
USE [msdb]
GO
EXEC msdb.dbo.sp_add_alert @name=N'Error - Severity 16',
@message_id=0,
@severity=16,
@enabled=1,
@delay_between_responses=0,
@include_event_description_in=1,
@category_name=N'[Uncategorized]',
@job_id=N'00000000-0000-0000-0000-000000000000'
Run Code Online (Sandbox Code Playgroud)
我很好奇为什么
SELECT 1/0;
Run Code Online (Sandbox Code Playgroud)
消息 8134,级别 16,状态 1,第 17 行 遇到除零错误。
没有引发错误,但是
BACKUP DATABASE MyDatabase TO DISK = 'C:\FolderThatDoesntexist'
Run Code Online (Sandbox Code Playgroud)
消息 3201,级别 16,状态 1,第 8 行 无法打开备份设备“C:\FolderThatDoesntexist”。操作系统错误 5(访问被拒绝。)。
消息 3013,级别 16,状态 1,第 8 行备份数据库异常终止。
曾是
这篇文章和它引用的博客文章表明 SQL Server 只会针对记录的错误引发事件,这可以在sys.messages
所以我查询sys.messages
了这些错误代码:
SELECT severity,
message_id,
is_event_logged
FROM sys.messages
WHERE language_id = 1033 AND
message_id IN (8134,3201,3013)
Run Code Online (Sandbox Code Playgroud)
但发现这三个都设置为0:
为什么 3201 …