Sql 使用存储过程的大容量插入

Sql 使用存储过程的大容量插入,sql,sql-server-2008,stored-procedures,bulkinsert,Sql,Sql Server 2008,Stored Procedures,Bulkinsert,我有一个很好的问题: BULK INSERT ZIPCodes FROM 'e:\5-digit Commercial.csv' WITH ( FIRSTROW = 2 , FIELDTERMINATOR = ',', ROWTERMINATOR = '\n' ) 但是现在我想为它创建一个存储过程 我已经编写了以下代码来创建其存储过程: create proc dbo.InsertZipCode @filepath varchar(500)='e:\5-

我有一个很好的问题:

BULK INSERT ZIPCodes 
FROM  'e:\5-digit Commercial.csv' 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)
但是现在我想为它创建一个存储过程

我已经编写了以下代码来创建其存储过程:

create proc dbo.InsertZipCode
@filepath varchar(500)='e:\5-digit Commercial.csv'
as
begin
BULK INSERT ZIPCodes 
FROM  @filepath 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)
end
但其显示错误:

Msg 102,15级,状态1,程序 InsertZipCode,第6行语法不正确 靠近“@filepath”

Msg 319,15级,状态1,程序 InsertZipCode,第7行语法不正确 靠近关键字“with”。如果这 语句是一个常用的表 表达式、xmlnamespaces子句或 一个变更跟踪上下文子句 之前的语句必须终止 用分号

请告诉我我做错了什么,我能做些什么使它在存储过程中工作


谢谢

您的存储过程代码没有问题-关键是:
大容量插入
命令不能接受文件名作为变量

这确实有效:

BULK INSERT ZIPCodes 
FROM  'e:\5-digit Commercial.csv' 
WITH 
但无论是否在存储过程中,这都不起作用:

DECLARE @filename VARCHAR(255)
SET @filename = 'e:\5-digit Commercial.csv' 

BULK INSERT ZIPCodes 
FROM @filename
WITH 
不幸的是,你不能这样做。您可以考虑将您的<代码>批量插入< /代码>语句作为字符串(具有固定文件名),然后将其作为动态SQL执行,但我没有真正看到任何其他解决方案。
DECLARE @filepath nvarchar(500)
SET @filepath = N'e:\5-digit Commercial.csv'

DECLARE @bulkinsert NVARCHAR(2000)

SET @bulkinsert = 
       N'BULK INSERT ZIPCodes FROM ''' + 
       @filepath + 
       N''' WITH (FIRSTROW = 2, FIELDTERMINATOR = '','', ROWTERMINATOR = ''\n'')'

EXEC sp_executesql @bulkinsert

您只需尝试一下,我认为您需要将此CSV文件直接上载到“E”驱动器。为此,我认为您需要拥有管理员权限,或者询问数据库管理人员

create procedure dbo.InsertZipCode
AS
BEGIN
SET NOCOUNT ON;
 BULK
   INSERT ZIPCodes from 'e:\5-digit Commercial.csv'
WITH
(
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\n'
)
END

如果您有权访问SQLCmd exe,则可以选择动态SQL

SqlCmd实用程序允许您使用-v参数传递字符串替换变量

您可以使用名为“filepath”的模板变量,当您通过cmdline执行脚本时,该变量将被替换

SQL脚本将如下所示:

BULK INSERT ZIPCodes 
FROM  '$(filepath)' 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)
end
然后,您将使用以下命令行执行脚本:

sqlcmd -b -S SERVER\INSTANCEHERE -E -i "PATH\FILENAMEHERE.Sql" -v FilePath = "e:\5-digit Commercial.csv" -s "|"
该示例的重要部分是-v参数:

-v FilePath = "e:\5-digit Commercial.csv"

谢谢,我已经把它作为一个字符串完成了,并使用exec运行它,但我认为可能还有其他一些解决方案。非常感谢。marc_s但是我可以从过程中执行EXEC sp_executesql@bulkinsert吗?因此,我的C#接口将调用我的SQL过程,将参数(文件路径、表名)传递到,它将创建字符串并调用动态SQL?这到底是什么?
create PROC TestInsert
    (
      @stuName NVARCHAR(50) ,
      @XmlData XML
    )
AS
    BEGIN
        BEGIN TRY 
            INSERT  INTO dbo.Test_Student
                    ( stuName 
                    )
            VALUES  ( @stuName
                    );
            DECLARE @id BIGINT;
            SET @id = ( SELECT  SCOPE_IDENTITY()
                      ); 
            INSERT  INTO dbo.Test_Qual
                    ( stuid ,
                      stuclass ,
                      InstituteId ,
                      obtmark ,
                      totalmark ,
                      per
                    )
                    SELECT  @id ,
                            col.value('stuclass[1]', 'nvarchar(50)') AS stuclass ,
                            col.value('InstituteId[1]', 'int') AS InstituteId ,
                            col.value('obtmark[1]', 'nvarchar(100)') AS obtmark ,
                            col.value('totalmark[1]', 'nvarchar(50)') AS totalmark ,
                            col.value('per[1]', 'nvarchar(50)') AS per
                    FROM    @XmlData.nodes('Parent/child') AS Doc ( col );  

            SELECT  @id AS RegisIdNUH ,
                    1 AS Flag ,
                    'Save' AS Msg
            FROM    dbo.Test_Student R
            WHERE   R.stuid = @id;

        END TRY
        BEGIN CATCH
            SELECT  0 AS Flag ,
                    'Some Error occur' AS Msg;
            ROLLBACK;
        END CATCH;
    END;