如何在 SQL Server 中对具有索引视图的表使用 bcp in

Joe*_*Joe 4 sql-server bcp

我正在使用 SQL Server 2017,并希望在脚本中使用“bcp in”来填充多个数据库中的表。我无法将数据导入到具有索引视图的表中。以下是重现我的问题的 MCVE:

  1. 运行本文末尾的脚本,用两个表、一个索引视图和一些数据填充测试数据库。

  2. 运行bcp out将表Table1中的测试数据导出到文件中:

bcp [dbo].[Table1] out .\Table1.bcp -S "localhost" -d TestDB -T -k -N
Run Code Online (Sandbox Code Playgroud)
  1. 删除表1中的测试数据:
DELETE FROM [dbo].[Table1]
Run Code Online (Sandbox Code Playgroud)
  1. 尝试使用bcp in将数据导入到 Table1 中:
bcp [dbo].[Table1] in .\Table1.bcp -S "localhost" -d TestDB -T -k -N
Run Code Online (Sandbox Code Playgroud)

结果:失败并显示错误消息INSERT failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'...

注意:如果我在视图上删除索引 [ix_v1],这将会成功:仅当表被索引视图引用时才会出现该问题。

  1. 尝试使用bcp in和 -q 开关将数据导入到 Table1 :
bcp [dbo].[Table1] in .\Table1.bcp -S "localhost" -d TestDB -T -k -N -q
Run Code Online (Sandbox Code Playgroud)

结果:失败并显示错误消息Invalid object name '[dbo].[Table1]'

  1. 尝试通过指定不带 [] 分隔符的表名并使用 -q 开关将数据导入到 Table1 中:
bcp dbo.Table1 in .\Table1.bcp -S ".\SqlExpress17" -d TestDB2 -T -k -N -q
Run Code Online (Sandbox Code Playgroud)

结果:数据导入成功。然而,这不满足我的要求,因为我想要一个通用脚本,该脚本也可以处理需要分隔符的表名(例如[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')
Run Code Online (Sandbox Code Playgroud)

Dan*_*man 6

-qbcp选项的文档指出:

将整个三部分表或视图名称括在引号 ("") 中

不要将各个对象名称部分括在方括号中,而是将整个限定对象名称参数括在双引号中。-d由于您指定了数据库上下文的选项,因此此处允许由两部分组成的名称:

bcp "dbo.Table1" in .\Table1.bcp -S ".\SqlExpress17" -d TestDB2 -T -k -N -q
Run Code Online (Sandbox Code Playgroud)

这将允许不符合常规标识符命名规则的对象名称。该-q选项还SET QUOTED_IDENTIFIER ON允许插入带有索引视图、过滤索引等的表。

但是,如果表名包含句点,您仍然会收到错误。一个未记录的解决方法是将架构和对象名称用双引号引起来:

bcp "dbo"."Table.NameWithDot" in .\Table1.bcp -S ".\SqlExpress17" -d TestDB2 -T -k -N -q
Run Code Online (Sandbox Code Playgroud)