Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从csv文件大容量插入-忽略有错误的行-SQL Server_Sql_Sql Server_Bulkinsert_Csv Import - Fatal编程技术网

从csv文件大容量插入-忽略有错误的行-SQL Server

从csv文件大容量插入-忽略有错误的行-SQL Server,sql,sql-server,bulkinsert,csv-import,Sql,Sql Server,Bulkinsert,Csv Import,我正在尝试将数据从csv文件导入SQL Server。csv文件中有数千个条目,其中有很多行的数据不正确 CSV文件中的某些行是: `"ID"|"EmpID"|"FName"|"LName"|"Gender"|"DateOfBirth" "1"|"90043041961"|"ABCD"|"TEST"|"F"|"1848-05-05 00:00:00.000" "1"|"10010161961"|"XYZ"|"TEST"|"F"|"1888-12-12 00:00:00.000" . . .. .

我正在尝试将数据从csv文件导入SQL Server。csv文件中有数千个条目,其中有很多行的数据不正确

CSV文件中的某些行是:

`"ID"|"EmpID"|"FName"|"LName"|"Gender"|"DateOfBirth"
"1"|"90043041961"|"ABCD"|"TEST"|"F"|"1848-05-05 00:00:00.000"
"1"|"10010161961"|"XYZ"|"TEST"|"F"|"1888-12-12 00:00:00.000"
.
.
..
..
....
"4"|"75101141821PPKKLL"|"LLKK"|"F"|"1925-09-09 00:00:00.000"|""
"4"|"32041401961UUYYTT"|"PPLL"|"M"|"1920-01-01 00:00:00.000"|""
.
.....
"25"|"00468132034"|"FGTT"|"OOOO"|"F"|"1922-11-11 00:00:00.000"
"25"|"00468132034"|"KKKK"|"PPPP"|"F"|"1922-11-11 00:00:00.000"
创建TestTable并尝试将数据(来自csv文件)插入其中:

我正在使用以下脚本将数据从csv文件导入SQL Server中的
TestTable

bulk insert TestTable
from 'C:\TestData.csv'
with 
   (firstrow = 2,
    DATAFILETYPE='char',
    FIELDTERMINATOR= '"|"',
    ROWTERMINATOR = '\n',
    ERRORFILE ='C:\ImportErrors.csv',
    MAXERRORS = 0,
    TABLOCK
   );
错误:

Msg 4863,第16级,状态1,第1行
第32763行第5列(性别)的大容量加载数据转换错误(截断)

Msg 4863,第16级,状态1,第1行
第32764行第5列(性别)的大容量加载数据转换错误(截断)

是否有任何方法可以忽略由于某些原因或其他原因无法添加的行(csv文件中),并插入具有正确语法的行

谢谢


PS:我不能使用SSIS。只允许使用SQL

我每周处理从不同来源收到的不同CSV文件,因此数据的质量很好,很干净,而其他数据则是噩梦。这就是我处理收到的CSV字段的方式,希望能对您有所帮助。您仍然需要添加一些数据验证来处理格式错误的数据

SET NOCOUNT ON
GO

-- Create Staging Table
    IF OBJECT_ID(N'TempDB..#ImportData', N'U') IS NOT NULL
        DROP TABLE #ImportData

    CREATE TABLE #ImportData(CSV NVARCHAR(MAX))

-- Insert the CSV Data
    BULK INSERT #ImportData
        FROM 'C:\TestData.csv' 

-- Add Control Columns
    ALTER TABLE #ImportData 
        ADD ID INT IDENTITY(1, 1)

    ALTER TABLE #ImportData 
        ADD Malformed BIT DEFAULT(0)

-- Declare Variables
    DECLARE @Deliminator NVARCHAR(5) = '|', @ID INT = 0, @DDL NVARCHAR(MAX)
    DECLARE @NumberCols INT = (SELECT LEN(CSV) - LEN(REPLACE(CSV, @Deliminator, '')) FROM  #ImportData WHERE ID = 1)

-- Flag Malformed Rows
    UPDATE #ImportData
        SET Malformed = CASE WHEN LEN(CSV) - LEN(REPLACE(CSV, @Deliminator, '')) != @NumberCols THEN 1 ELSE 0 END

-- Create Second Staging Table
    IF OBJECT_ID(N'TestTable', N'U') IS NOT NULL
        DROP TABLE TestTable

    CREATE table TestTable
        (ID varchar(4000),
        EmpID varchar(4000),
        FName varchar(4000),
        LName varchar(4000),
        Gender varchar(4000),
        DateOfirthB varchar(4000));

-- Insert CSV Rows
    WHILE(1 = 1)
        BEGIN
            SELECT TOP 1
                @ID = ID
                ,@DDL = 'INSERT INTO TestTable(ID, EmpID, FName, LName, Gender, DateOfirthB)' + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), 1)
                            + 'VALUES' -- + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), 2)
                                    + '(' + DDL + ')'
            FROM
                (
                    SELECT 
                        ID
                        ,DDL = '''' + REPLACE(REPLACE(REPLACE(CSV, '''', ''''''), @Deliminator, ''','''), '"', '')  + ''''
                    FROM  
                        #ImportData 
                    WHERE 
                        ID > 1
                        AND Malformed = 0) D
            WHERE
                ID > @ID
            ORDER BY
                ID

            IF @@ROWCOUNT = 0 BREAK

            EXEC sp_executesql @DDL
        END

-- Clean Up
    IF OBJECT_ID(N'TempDB..#ImportData', N'U') IS NOT NULL
        DROP TABLE #ImportData

-- View Results
    SELECT * FROM dbo.TestTable
既然OP声明“[…]插入语法正确的那个”,我想知道为什么没有人建议修改MAXERRORS子句。尽管并非所有的错误都可以伪装,但它对于转换错误来说效果很好。
因此,我的建议是使用MAXERRORS=999代替MAXERRORS=0(根据最初的示例)。

我知道这并不能回答您的问题,但我真诚地认为您最好尝试使用SSI来完成这项工作,而不是使用原始SSIsql@DForck42--我希望我能使用SSIS,但不能。我只能为此使用SQL…感谢您的建议,尽管通常的过程是首先将数据导入一个更宽容的暂存表(即所有字段都是NVARCHAR(4000))。然后使用SQL清理数据并将其移动到最终的表中。就我个人而言,我更喜欢这种方法而不是SSISmyself@Nick.McDermaid--好的。。我使用NVARCHAR(4000)将数据导入一个暂存表,然后清理它。。。听起来不错。。但是,csv表中有一些行,如
“4”|“75101141821PPKKLL”|“LLKK”|“F”|“1905-05-05 00:00:00.000”|“
,其中有一个额外的列条目。。我怎么能忽略这些?你的意思是说你有一个额外的管道,所以看起来有太多的列?将整行导入到一列中,然后再次使用SQL清理并拆分列。听起来很蠢,但很管用。事实上,如果要使用SSI,您也会遇到同样的问题-如果文本驱动程序无法正确识别列,则需要导入整行并手动拆分PSST:它不是
@Deliminator
它的
@Deliminator
。但不管怎么说,我还是故意在我发布的代码中拼错单词,如果我在其他网站上看到它,我知道它来自哪里;-),谢谢@MarkKram--非常感谢这应该是一个评论而不是回答,请用详细的解决方案更新你的帖子,
SET NOCOUNT ON
GO

-- Create Staging Table
    IF OBJECT_ID(N'TempDB..#ImportData', N'U') IS NOT NULL
        DROP TABLE #ImportData

    CREATE TABLE #ImportData(CSV NVARCHAR(MAX))

-- Insert the CSV Data
    BULK INSERT #ImportData
        FROM 'C:\TestData.csv' 

-- Add Control Columns
    ALTER TABLE #ImportData 
        ADD ID INT IDENTITY(1, 1)

    ALTER TABLE #ImportData 
        ADD Malformed BIT DEFAULT(0)

-- Declare Variables
    DECLARE @Deliminator NVARCHAR(5) = '|', @ID INT = 0, @DDL NVARCHAR(MAX)
    DECLARE @NumberCols INT = (SELECT LEN(CSV) - LEN(REPLACE(CSV, @Deliminator, '')) FROM  #ImportData WHERE ID = 1)

-- Flag Malformed Rows
    UPDATE #ImportData
        SET Malformed = CASE WHEN LEN(CSV) - LEN(REPLACE(CSV, @Deliminator, '')) != @NumberCols THEN 1 ELSE 0 END

-- Create Second Staging Table
    IF OBJECT_ID(N'TestTable', N'U') IS NOT NULL
        DROP TABLE TestTable

    CREATE table TestTable
        (ID varchar(4000),
        EmpID varchar(4000),
        FName varchar(4000),
        LName varchar(4000),
        Gender varchar(4000),
        DateOfirthB varchar(4000));

-- Insert CSV Rows
    WHILE(1 = 1)
        BEGIN
            SELECT TOP 1
                @ID = ID
                ,@DDL = 'INSERT INTO TestTable(ID, EmpID, FName, LName, Gender, DateOfirthB)' + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), 1)
                            + 'VALUES' -- + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), 2)
                                    + '(' + DDL + ')'
            FROM
                (
                    SELECT 
                        ID
                        ,DDL = '''' + REPLACE(REPLACE(REPLACE(CSV, '''', ''''''), @Deliminator, ''','''), '"', '')  + ''''
                    FROM  
                        #ImportData 
                    WHERE 
                        ID > 1
                        AND Malformed = 0) D
            WHERE
                ID > @ID
            ORDER BY
                ID

            IF @@ROWCOUNT = 0 BREAK

            EXEC sp_executesql @DDL
        END

-- Clean Up
    IF OBJECT_ID(N'TempDB..#ImportData', N'U') IS NOT NULL
        DROP TABLE #ImportData

-- View Results
    SELECT * FROM dbo.TestTable