我们在 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 上查找 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 with ANSWER: 正如下面有用的答案所指出的,我不得不把
SET QUOTED_IDENTIFIER ON
在 SQL 的顶部使其正常工作。
SET QUOTED_IDENTIFIER ON
当我使用它创建索引时没有效果。