Joh*_*hnG 4 sql-server t-sql error-handling sql-server-2019
我正在使用 SQL Server 2019 并发现了一个奇怪的行为。研究并没有让我走得更远。
有人可以解释这种行为吗?
SET QUOTED_IDENTIFIER ON;
if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off';
BEGIN TRY
if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off';
END TRY
BEGIN CATCH
if ((256 & @@options) = 256) print '3- quoted_identifier is on' else print '3- quoted_identifier is off';
-- SET QUOTED_IDENTIFIER OFF
-- if ((256 & @@options) = 256) print '4- quoted_identifier is on' else print '4- quoted_identifier is off';
END CATCH
Run Code Online (Sandbox Code Playgroud)
返回:
1- quoted_identifier is on
2- quoted_identifier is on
Run Code Online (Sandbox Code Playgroud)
但以下代码:
SET QUOTED_IDENTIFIER ON;
if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off';
BEGIN TRY
if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off';
END TRY
BEGIN CATCH
if ((256 & @@options) = 256) print '3- quoted_identifier is on' else print '3- quoted_identifier is off';
SET QUOTED_IDENTIFIER OFF
if ((256 & @@options) = 256) print '4- quoted_identifier is on' else print '4- quoted_identifier is off';
END CATCH
Run Code Online (Sandbox Code Playgroud)
返回:
1- quoted_identifier is off
2- quoted_identifier is off
Run Code Online (Sandbox Code Playgroud)
即使它没有进入捕获!我肯定错过了什么。
我什至能够将代码简化为最简单的:
SET QUOTED_IDENTIFIER ON;
if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off';
SET QUOTED_IDENTIFIER OFF
if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off';
Run Code Online (Sandbox Code Playgroud)
结果:
1- quoted_identifier is off
2- quoted_identifier is off
Run Code Online (Sandbox Code Playgroud)
我有一些使用 的代码FOR XML,这要求我将引用的标识符设置为 ON,但我需要将其重新设置为 OFF,无论 XML 部分是成功还是失败。你会怎么做?
我的测试表明,如果我将SET QUOTED_IDENTIFIERto off 放在 the 中CATCH,则插入无法说明我引用的标识符设置不正确,尽管它设置在TRYto的开头ON。
对于顶级临时批处理解析开始使用会话的当前设置
QUOTED_IDENTIFIER。当批处理被解析时,任何发生都SET QUOTED_IDENTIFIER将改变从那时起的解析行为,并为会话保存该设置。所以在批处理被解析和执行后,会话的QUOTED_IDENTIFER设置将根据SET QUOTED_IDENTIFIER批处理中的最后一次出现来设置。
因此,的行为QUOTED_IDENTIFIER取决于批处理的解析,而不是执行。解析批处理开始时的默认值来自当前连接设置。
@@OPTIONS只显示当前的默认值,如果批处理被解析将使用。这就是为什么 SSMS 总是放在SET一个单独的批次中。
的执行SET与 的行为无关@@OPTIONS,除了更改以后批次的默认值。
set QUOTED_IDENTIFIER on;
create table "select"(i int);
drop table "select";
GO
set QUOTED_IDENTIFIER off;
create table "select"(i int);
drop table "select";
-- Incorrect syntax near 'select'.
GO
set QUOTED_IDENTIFIER off;
if (1=0)
begin
set QUOTED_IDENTIFIER on;
end
create table "select"(i int);
drop table "select";
GO
set QUOTED_IDENTIFIER on;
if (1=0)
begin
set QUOTED_IDENTIFIER off;
end
create table "select"(i int);
drop table "select";
-- Incorrect syntax near 'select'.
GO
Run Code Online (Sandbox Code Playgroud)
Charlieface的答案似乎已经适当地解释了您在使用时描述的行为的原因SET QUOTED_IDENTIFIER,因此,如果您需要在 SP 内使用它,我将留下一个可以使用的方法:
QUOTED_IDENTIFIER将批处理的一部分隔离到另一个过程中,并从需要OFF这样的过程中调用它: db<>fiddle - 在您的计算机上运行 2 个不同的会话,因为我无法使其在 dbfiddle 上正常运行。
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |