具有主键Id的SQL Server大容量插入



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

我仍然收到错误

无法将值NULL插入列"CNPJ_ID"、表"CVM.dbo.Hist"中;列不允许为null。INSERT失败。

有什么建议吗?

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:anaconda3Docs2022.csv'
WITH (
FIELDTERMINATOR = ';',
ROWTERMINATOR = '0x0a',
FIRSTROW =2,
ROWS_PER_BATCH = 100000
);

我们没有您的源文件:"C:\anaconda3\Docs\2022.csv"。因此,没有提供可重复的最小示例。

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

如果数据文件不包含中标识列的值对于表或视图,请使用格式文件指定标识导入数据时将跳过表或视图中的列;SQL服务器会自动为列指定唯一值。

这里有一个概念示例。

源文件: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='rn' 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:TempmyIdentity_No_PK.csv',
FORMATFILE='e:TempmyIdentity_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 |
+----------+-----------+-----------+------------+

使用OPENROWSET(BULK…(,就可以编写一个普通的INSERT。。。选择。

这已经几年了,但IIRC你想要bcp-E。除非使用格式化文件,否则源文件的列数必须与正在加载的表的列数相同。-E选项使SQL Server忽略文件中"标识"列的值,而代之以自己的值。

最新更新