Sql-Server

如何在 SQL Server 中具有索引視圖的表上使用 bcp in

  • April 7, 2022

我正在使用 SQL Server 2017,並希望在腳本中使用“bcp in”來填充多個數據庫中的表。我無法將數據導入具有索引視圖的表中。以下是重現我的問題的 MCVE:

  1. 執行本文末尾的腳本,用兩個表、一個索引視圖和一些數據填充一個測試數據庫。
  2. 執行bcp out將表 Table1 中的測試數據導出到文件中:
bcp [dbo].[Table1] out .\Table1.bcp -S "localhost" -d TestDB -T -k -N
  1. 從表1中刪除測試數據:
DELETE FROM [dbo].[Table1]
  1. 嘗試使用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 $$在視圖上,這將成功:僅當表被索引視圖引用時才會出現問題。

  1. 嘗試使用帶有 -q 開關的bcp in將數據導入 Table1 :
bcp [dbo].[Table1] in .\Table1.bcp -S "localhost" -d TestDB -T -k -N -q

結果:失敗並顯示錯誤消息Invalid object name '[dbo].[Table1]'

  1. 嘗試通過不指定表名將數據導入 Table1$$ $$分隔符,並使用 -q 開關:
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 部分名稱:

bcp "dbo.Table1" in .\Table1.bcp -S ".\SqlExpress17" -d TestDB2 -T -k -N -q

這將允許不符合正常標識符命名規則的對象名稱。該-q選項還SET QUOTED_IDENTIFIER ON允許插入帶有索引視圖、過濾索引等的表。

但是,如果表名包含句點,您仍然會收到錯誤消息。一個未記錄的解決方法是將架構和對象名稱都括在雙引號中:

bcp "dbo"."Table.NameWithDot" in .\Table1.bcp -S ".\SqlExpress17" -d TestDB2 -T -k -N -q

引用自:https://dba.stackexchange.com/questions/310571