我正在使用 SQL Server 2017,并希望在脚本中使用“bcp in”来填充多个数据库中的表。我无法将数据导入具有索引视图的表中。以下是重现我的问题的 MCVE:
运行本文末尾的脚本,用两个表、一个索引视图和一些数据填充一个测试数据库。
运行bcp out将表 Table1 中的测试数据导出到文件中:
bcp [dbo].[Table1] out .\Table1.bcp -S "localhost" -d TestDB -T -k -N
- 从表1中删除测试数据:
DELETE FROM [dbo].[Table1]
- 尝试使用bcp in将数据导入 Table1 :
bcp [dbo].[Table1] in .\Table1.bcp -S "localhost" -d TestDB -T -k -N
结果:失败并显示错误消息INSERT failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'...
注意:如果我在视图上删除索引 [ix_v1],这将成功:只有在索引视图引用表时才会出现问题。
- 尝试使用带有 -q 开关的bcp in将数据导入 Table1 :
bcp [dbo].[Table1] in .\Table1.bcp -S "localhost" -d TestDB -T -k -N -q
结果:失败并显示错误消息Invalid object name '[dbo].[Table1]'
- 尝试通过指定不带 [] 分隔符的表名并使用 -q 开关将数据导入 Table1:
bcp dbo.Table1 in .\Table1.bcp -S ".\SqlExpress17" -d TestDB2 -T -k -N -q
结果:数据成功导入。但是,这不符合我的要求,因为我想要一个通用脚本,它也可以处理需要分隔符的表名(例如[dbo].[My Table]
)。
问题:有没有办法使用 bcp 将数据导入具有索引视图的表中,同时在 bcp 命令行上指定一个分隔的、模式限定的表名?
填充空数据库 TestDB 的脚本
USE [TestDB]
GO
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table1](
[Table1Id] [int] NOT NULL,
[Table1Name] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ( [Table1Id] ASC)
)
GO
CREATE TABLE [dbo].[Table2](
[Table2Id] [int] NOT NULL,
[Table2Name] [nvarchar](50) NOT NULL,
[Table1Id] [int] NULL,
CONSTRAINT [PK_Table2] PRIMARY KEY CLUSTERED ( [Table2Id] ASC)
)
GO
CREATE VIEW [dbo].[v1] WITH SCHEMABINDING
AS
SELECT
T1.Table1Id, T1.Table1Name,
T2.Table2Id, T2.Table2Name
FROM [dbo].[Table1] T1 INNER JOIN [dbo].[Table2] T2
ON T1.Table1Id = T2.Table1Id
GO
CREATE UNIQUE CLUSTERED INDEX [ix_v1] ON [dbo].[v1] (Table1Name, Table2Name)
GO
INSERT INTO Table1
VALUES
(1, 'One')
,(2,'Two')
bcp
-q
选项的文档指出:不要将单个对象名称部分括在方括号中,而是将整个限定的对象名称参数括在双引号中。
-d
由于您为数据库上下文指定了选项,因此此处允许使用 2 部分名称:这将允许不符合常规标识符命名规则的对象名称。该
-q
选项还SET QUOTED_IDENTIFIER ON
允许插入带有索引视图、过滤索引等的表。但是,如果表名包含句点,您仍然会收到错误消息。一个未记录的解决方法是将架构和对象名称都括在双引号中: