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 |
+----------+-----------+-----------+------------+
我想将 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 |
+----------+-----------+-----------+------------+