SQL 带有主键 ID 的服务器批量插入

SQL Server Bulk Insert with Primary Key Id

我想将 csv 文件批量插入此 table。我的 csv 没有增量 pk 字段,所以我创建了一个没有 pk 列的 table 视图,并尝试在视图中批量插入。

我仍然遇到错误

Cannot insert the value NULL into column 'CNPJ_ID', table 'CVM.dbo.Hist'; column does not allow nulls. INSERT fails.

有什么建议吗?

CREATE TABLE [dbo].[Hist]
(
    [CNPJ_ID] [INT] IDENTITY(1,1) PRIMARY KEY,
    [TP_FUNDO] [text] NULL,
    [CNPJ_FUNDO] [nvarchar](max) NULL,
    [DT_COMPTC] [varchar](50) NOT NULL,
    [VL_TOTAL] [varchar](50) NOT NULL,
    [VL_QUOTA] [varchar](50) NOT NULL,
    [VL_PATRIM_LIQ] [varchar](50) NOT NULL,
    [CAPTC_DIA] [varchar](50) NOT NULL,
    [RESG_DIA] [varchar](50) NOT NULL,
    [NR_COTST] [int] NULL   
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

CREATE VIEW [VWHist] AS
    SELECT 
        [TP_FUNDO],
        [CNPJ_FUNDO],
        [DT_COMPTC],
        [VL_TOTAL],
        [VL_QUOTA],
        [VL_PATRIM_LIQ],
        [CAPTC_DIA],
        [RESG_DIA],
        [NR_COTST]
    FROM 
        Hist;

BULK INSERT [dbo].[VWHist]
FROM 'C:\anaconda3\Docs22.csv'
    WITH (
    FIELDTERMINATOR = ';',
    ROWTERMINATOR = '0x0a',
    FIRSTROW =2,
    ROWS_PER_BATCH = 100000
    );

改用OPENROWSET(BULK . . .),你可以写一个普通的INSERT ... SELECT。

已经好几年了,但是 IIRC 你想要 bcp -E。除非您使用格式文件,否则您的源文件必须具有与您正在加载的 table 相同的列数。 -E 选项导致 SQL 服务器忽略文件中 Identity 列的值,并替换为它自己的值。

我们没有您的源文件:'C:\anaconda3\Docs22.csv'。所以没有提供最小的可复制示例。

官方文档 [KEEPIDENTITY][1] 明确说明了如何处理您的场景:

If the data file does not contain values for the identity column in the table or view, use a format file to specify that the identity column in the table or view is to be skipped when importing data; SQL Server automatically assigns unique values for the column.

这是一个概念性的例子。

源文件:myIdentity_No_PK.csv

Anthony,Grosse,1980-02-23
Alica,Fatnowna,1963-11-14
Stella,Rosenhain,1992-03-02
Miller,Dylan,1954-01-05

XML 格式文件:myIdentity_No_PK.xml

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <RECORD>
      <FIELD ID="1" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="70"/>
      <FIELD ID="2" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="70"/>
      <FIELD ID="3" xsi:type="CharTerm" TERMINATOR='\r\n' MAX_LENGTH="10"/>
   </RECORD>
   <ROW>
      <COLUMN SOURCE="1" NAME="FirstName" xsi:type="SQLVARYCHAR"/>
      <COLUMN SOURCE="2" NAME="LastName" xsi:type="SQLVARYCHAR"/>
      <COLUMN SOURCE="3" NAME="BirthDate" xsi:type="SQLDATE"/>
   </ROW>
</BCPFORMAT>

SQL

USE tempdb;
GO

DROP TABLE IF EXISTS dbo.myIdentity;

CREATE TABLE dbo.myIdentity ( 
   PersonID smallint IDENTITY(1,1) NOT NULL,
   FirstName varchar(25) NOT NULL,
   LastName varchar(30) NOT NULL,
   BirthDate date
);

INSERT INTO dbo.myIdentity (FirstName, LastName, BirthDate)
SELECT * FROM  OPENROWSET(
BULK 'E:\Temp\myIdentity_No_PK.csv',
FORMATFILE='e:\Temp\myIdentity_No_PK.xml') as t;


-- review results
SELECT * FROM dbo.myIdentity;

输出

+----------+-----------+-----------+------------+
| PersonID | FirstName | LastName  | BirthDate  |
+----------+-----------+-----------+------------+
|        1 | Anthony   | Grosse    | 1980-02-23 |
|        2 | Alica     | Fatnowna  | 1963-11-14 |
|        3 | Stella    | Rosenhain | 1992-03-02 |
|        4 | Miller    | Dylan     | 1954-01-05 |
+----------+-----------+-----------+------------+