0

我的问题与 UPDATE failed 有点相关,因为以下 SET 选项的设置不正确: 'QUOTED_IDENTIFIER'

我正在使用SQL 查询通知为我的应用程序从数据库启用缓存,并且遇到了我无法完全解释的奇怪行为。

如果我运行一些 SQL 查询通知代码

using (SqlCommand command=new SqlCommand("SELECT MyColumn1, MyColumn2, etc... FROM dbo.StockSupplierCode", connection))
{
    SqlDependency dependency=new SqlDependency(command);
    dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);
    command.ExecuteReader();    
}

第一次在我的数据库上运行此操作后,如果我尝试更新受影响的表,则会收到错误消息:

消息 1934,级别 16,状态 1,过程 Stock_NonIntTrigger,第 14 行 [批处理开始行 0] 更新失败,因为以下 SET 选项的设置不正确:'QUOTED_IDENTIFIER'。验证 SET 选项对于索引视图和/或计算列上的索引和/或过滤索引和/或查询通知和/或 XML 数据类型方法和/或空间索引操作是否正确。

该错误专门指它发生在我的数据库中名为Stock_NonIntTrigger.

现在,只要我随后尝试更新此表,此错误就会持续存在。

但是,如果我打开此触发器,不进行任何更改并重新保存,错误就会消失。

我唯一的假设是,当我重新保存此触发器时,SQL 查询分析器可能正在添加 QUOTE_IDENTIFIER ON 语法,但是当我使用它重新打开同一个触发器时,sp_helptext它似乎不受影响并且与原始触发器相同。

然而,更新现在将成功。

任何能够提供任何见解的人:

  1. 为什么查询通知会导致此错误?
  2. 为什么重新保存触发器会使错误消失?
4

1 回答 1

2

创建触发器时有效的QUOTED_IDENTIFIERANSI_NULL会话设置作为对象元数据持久保存。这些在运行时使用并覆盖触发器范围内的当前会话设置。此行为也适用于存储过程、函数和视图。

创建对象时请注意确保两者QUOTED_IDENTIFIER都打开。ANSI_NULL这些选项在 SSMS 中默认启用,但出于向后兼容性的原因,在 SQLCMD 中不启用。我建议总是指定-ISQLCMD 参数来打开带引号的标识符以避免这个问题。

关于查询通知,SQL Server 需要正确设置“magic 7”会话选项才能使用此功能。这些与索引视图和过滤索引等其他功能所需的选项相同:

SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET NUMERIC_ROUNDABORT OFF
SET QUOTED_IDENTIFIER ON

默认情况下,所有这些选项都由具有 SQL Server 2005+ 数据库兼容性级别的现代 SQL Server API 正确设置。但是,由于不注意细节,持久设置是一个常见问题。

于 2020-05-21T09:50:29.653 回答