我们已在SQL Server 2016数据库的表中放置以下过滤索引:
CREATE UNIQUE NONCLUSTERED INDEX [fix_SystemPKeyExecutionOrder] ON [DataInt].[TaskMaster]
(
[SystemPkey] ASC,
[ExecutionOrder] ASC
)
WHERE ([ExecutionOrder] IS NOT NULL)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95)
GO
现在导致SQL代码失败的原因是以下错误:
UPDATE失败,因为以下SET选项不正确 设置:' QUOTED_IDENTIFIER'。验证SET选项是否正确 与计算列和/或的索引视图和/或索引一起使用 过滤的索引和/或查询通知和/或XML数据类型 方法和/或空间索引操作。 [SQLSTATE 42000](错误 1934年)。步骤失败了。
删除过滤后的索引后,代码运行完美。
关注MSDN for Index Options,对QUOTED_IDENTIFIERS一无所知。
我们的SQL代码中的UPDATE语句都没有任何值的双引号。我们可以看到的唯一双引号如下:
SET @ROWCOUNT = @@ROWCOUNT
If (@ROWCOUNT = 0)
BEGIN
RAISERROR('The "File Import" task ACTIVE_YN could not be updated to "Y". Either the task does not exist or the system "File Import To Stage" does not exist.', 16, 1)
END
ELSE
BEGIN
Print 'Successfully updated the "File Import" task ACTIVE_YN to "Y".'
END
即使我们改变了那些双引号"对于两个单引号'',代码仍会失败并出现相同的错误。
表格本身是用:
创建的SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [DataInt].[TaskMaster](
[Pkey] [bigint] IDENTITY(1,1) NOT NULL,
[ScheduleMasterPkey] [int] NOT NULL,
[SystemPkey] [int] NOT NULL,
[SourcePkey] [int] NOT NULL,
[TargetPkey] [int] NOT NULL,
[TaskName] [varchar](255) NOT NULL,
[TaskTypePkey] [int] NOT NULL,
[Active_YN] [char](1) NOT NULL,
[ModifiedDate] [datetime] NULL,
[ModifiedBy] [varchar](100) NULL,
[RowVersion] [timestamp] NOT NULL,
[ExecutionOrder] [int] NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
[Pkey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95) ON [PRIMARY],
CONSTRAINT [uc_TaskName] UNIQUE NONCLUSTERED
(
[TaskName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95) ON [PRIMARY]
) ON [PRIMARY]
GO
就像我说的那样,如果我们不创建过滤索引,整个代码就会完美运行;它只会失败并带有索引。
那么为什么过滤后的索引突然导致我们的SQL轰炸?我们如何解决?
更新:这里有一小段代码可以重现失败。此代码通过SQL代理作业运行。删除索引后,此代码按预期运行,说明任务不存在的错误:
DECLARE @ROWCOUNT INT = 0
UPDATE [DataIntegrationMaster].[DataInt].[TaskMaster]
Set Active_YN = 'Y'
where TaskName = 'File Import'
and SystemPkey = 0
SET @ROWCOUNT = @@ROWCOUNT
If (@ROWCOUNT = 0)
BEGIN
RAISERROR('The "File Import" task ACTIVE_YN could not be updated to "Y". Either the task does not exist or the system "File Import To Stage" does not exist.', 16, 1)
END
ELSE
BEGIN
Print 'Successfully updated the "File Import" task ACTIVE_YN to "Y".'
END
UPDATE2与答案: 正如下面的有用答案所指出的,我不得不把
SET QUOTED_IDENTIFIER ON
位于SQL的顶部,以使其正常工作。
SET QUOTED_IDENTIFIER ON
当我使用它创建索引时,没有效果。
答案 0 :(得分:3)
有:SET QUOTED_IDENTIFIER (Transact-SQL)
为了防止出现类似问题,我建议您检查创建过滤索引的确切要求:CREATE INDEX (Transact-SQL)。它有一个很好的整洁表,显示了创建过滤索引所需的SET
选项。
答案 1 :(得分:3)
正如@Roger Wolf的回答所指出的,创建过滤索引要求您将QUOTED_IDENTIFER
设置设置为ON
,这就是您所做的。如果你没有这样做,你将无法在第一时间创建过滤索引。
但是,一旦创建,似乎该表上的任何DML操作(不仅仅是更新)都要求您将QUOTED_IDENTIFER
设置设置为ON
。这是您目前所缺少的,以及您收到错误的原因。
所以,我不知道你的update
的上下文是什么,你是将它作为临时语句运行,还是作为存储过程的一部分。无论哪种方式,请确保在开头的某处包含SET QUOTED_IDENTIFIER ON
语句。