Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/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
Sql server 无最后一行的大容量插入.csv_Sql Server_Database - Fatal编程技术网

Sql server 无最后一行的大容量插入.csv

Sql server 无最后一行的大容量插入.csv,sql-server,database,Sql Server,Database,我有一个带有多行数据的.csv文件,请参见图片 此数据由第三方提供,我无法更改格式 我正在使用ms SQL server管理将此数据批量插入SQL server表中 当我使用以下命令大容量插入时: BULK INSERT #tempDERIVEDDATA FROM 'C:\MyDownloads\Data.csv' WITH (FIRSTROW = 1, FIELDTERMINATOR = ',', ROWTERMINATOR = '0x0a',

我有一个带有多行数据的.csv文件,请参见图片

此数据由第三方提供,我无法更改格式

我正在使用ms SQL server管理将此数据批量插入SQL server表中

当我使用以下命令大容量插入时:

    BULK INSERT #tempDERIVEDDATA
    FROM 'C:\MyDownloads\Data.csv'
    WITH
    (FIRSTROW = 1,
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '0x0a',
    ERRORFILE = 'C:\MyDownloads\logfile.log')
    GO
我似乎得到了以下错误:

Msg 4832,16级,状态1,第236行批量加载:意外结束 在数据文件中遇到了个文件。味精7399,16级,状态 1,第236行链接服务器的OLE DB提供程序批量为空 报告了一个错误。该提供商没有提供任何有关该事件的信息 错误Msg 7330,级别16,状态2,第236行无法从中获取行 链接服务器的OLE DB提供程序批量为空

当删除最后一行(即页脚行)并说明文件中的行数时,大容量插入工作。因此,我甚至不能在放入表中时删除该行,因为我很难做到这一点

然后我想,如果使用OPENROWSET函数并计算行数,然后在表中插入行-1,会怎么样

因此,我尝试了以下方法来计算行数:

   DECLARE @lastrow INT
   SET @lastrow = (SELECT COUNT(*) FROM OPENROWSET(BULK 'C:\MyDownloads\DATA1.csv', 
   FORMATFILE = 'C:\MyDownloads\format.fmt',
   MAXERRORS=10) AS  ) - 1
   SELECT @lastrow
select last row应该检索行数-1应该检索行数,但我得到一个错误

Msg 4832,16级,状态1,第230行批量加载:意外结束 在数据文件中遇到文件。味精7399,16级,状态1, 第230行链接服务器的OLE DB提供程序批量为空 报告了一个错误。该提供商没有提供任何有关该事件的信息 错误Msg 7330,级别16,状态2,第230行无法从中获取行 链接服务器的OLE DB提供程序批量为空

文件格式如下所示:

在这之后,我决定用一个格式化文件,而不是单文件。这一次没有错误,但文件在应该检索“341”时检索“0”行


如果有人能帮忙,我将不胜感激。

考虑使用openrowset

    create procedure [dbo].LoadData
    (
            @file nvarchar(200)=null
    )
    as
    begin
            declare @sql varchar(max)
            set @sql='INSERT INTO DBO.Table
            (
                    column1, column2
            )
            select column1
                                    ,column2
            from openrowset(bulk N''' + @file +''',
             formatfile = N''d:\xml\Table.xml'') as t1
             where not column1 like (''Total'')'

             print @sql
             exec (@sql)
    end


    --- Table.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="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
      <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
     </RECORD>
     <ROW>
      <COLUMN SOURCE="1" NAME="column1" xsi:type="SQLNVARCHAR"/>
      <COLUMN SOURCE="2" NAME="column2" xsi:type="SQLNVARCHAR"/>
     </ROW>
    </BCPFORMAT>

嗯,我在2015年也遇到过同样的问题。你是不是碰巧在CapIQ工作?无论如何,我最终创建了一个C可执行文件并运行它来清理文件,然后运行大容量插入脚本来加载数据。实际上,我保存了这个解决方案,因为我认为有一天我会再次需要它。这是解决办法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;


namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {

            string sourceDirectory = @"C:\ManagedCode\Downloads\";
            try
            {
                var txtFiles = Directory.EnumerateFiles(sourceDirectory);

                foreach (string currentFile in txtFiles)
                {
                    //foreach (var currentFile in files)
                    {
                        var lines = File.ReadAllLines(currentFile);

                        //Just an example of changing the filename based upon the current name
                        var targetFile = Path.ChangeExtension(currentFile, "prod.txt");
                        File.WriteAllLines(targetFile, lines.Skip(1).Take(lines.Count() - 2));
                        //};

                    }

                }
            }

            catch (Exception ex)
            {

            }

        }
    }
}

您可以使用Windows任务管理器按照您选择的任何计划运行此可执行文件和任何可执行文件。

创建一个具有单个宽列的临时表,并将整行插入整个文件的该列,然后使用select+insert从临时表中进行选择,在选择时通过分隔符分隔字段,并排除最后一行。最后,在准备下一次导入时删除临时表。

通过指定要读取的最后一行号,尝试使用大容量插入命令的LASTROW选项。因此,如果有100行,可以指定LASTROW=99。@这是我采用的解决方案,但csv文件中的行数不是静态的。每个文件都是不同的,因此我需要检索行,这是代码试图实现的第二位。我将在大容量插入中使用LASTROW为什么不在执行大容量插入之前删除csv中的最后一行?@ejohnson,我采用了使用VBA删除最后一行的方法,但由于有太多的行和大约12个文件被下载,这太耗时了。这种方法是最有效的,只是我遇到的这个问题把我甩了回去。我建议两种选择:1。将数据插入一个全部为varchar的表中,并从中删除最后一行。2.在导入之前,请使用合适的工具(如powershell)删除文件中的最后一行。您好,Vicosanz,感谢您提供的上述信息,非常感谢。当我执行该过程时,我得到以下错误,我做错了什么?插入tempDERIVEDATA column1,column2从OpenRowsBulk N'C:\MyDownloads\DERBMDATA\DERBMDATA1.csv'+@file+',选择column1,column2,formatfile=N'd:\xml\Table.xml'作为t1,其中不是像'FTR'Msg 102一样的列1,级别15,状态1,第77行“+”附近的语法不正确。Msg 105,第15级,状态1,第79行字符串后未闭合的引号。这是正确的形式:插入tempDERIVEDATA column1,column2从openrowsetbulk N'C:\MyDownloads\DERBMDATA\DERBMDATA1.csv'中选择column1,column2,formatfile=N'd:\xml\Table.xml'作为t1,而不是像'FTR'那样的column1,因此我尝试使用您的方法,但仍然得到相同的错误。下面的错误:不,不幸的是我没有。我最终使用python解决了这个问题,类似于您在c上所做的。代码只是以sql识别的.csv格式下载数据。是的,是的,是的,Python将非常轻松地处理该任务。如果我现在必须这样做,我会使用Python。几年前,当我做这些事情的时候 ,我甚至不知道Python是什么。英雄联盟