使用存储过程批量插入

时间:2010-10-29 09:55:06

标签: 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-digit Commercial.csv'
as
begin
BULK INSERT ZIPCodes 
FROM  @filepath 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)
end

但显示错误:

  

Msg 102,Level 15,State 1,Procedure   InsertZipCode,第6行语法不正确   靠近'@filepath'。

     

Msg 319,Level 15,State 1,Procedure   InsertZipCode,第7行语法不正确   靠近关键字'with'。如果这   声明是一个常见的表格   表达式,xmlnamespaces子句或   一个变更跟踪上下文子句,   必须终止先前的陈述   用分号。

请告诉我我做错了什么以及如何使其在存储过程中正常工作。

由于

4 个答案:

答案 0 :(得分:39)

存储过程代码没有任何问题 - 重点是:BULK INSERT命令无法接受文件名作为变量。

这确实有效:

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 

不幸的是,你不能这样做。您可以考虑将BULK INSERT语句构建为字符串(具有固定文件名),然后将其作为动态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

答案 1 :(得分:0)

您只是尝试一下,我认为您需要将此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

答案 2 :(得分:0)

如果可以访问SQLCmd exe,则可以使用动态SQL替代。

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

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

SQL脚本如下所示:

iamRoleStatements:
  - Effect: "Allow"
    Action:
      - "s3:PutObject"
      - "s3:DeleteObject"
      - "s3:DeleteObjects"
    Resource: arn:aws:s3:::${self:custom.s3WwwBucket}/content/pages/*
  - Effect: Allow
    Action:
      - lambda:InvokeFunction
      - lambda:InvokeAsync
    Resource: arn:aws:lambda:${self:custom.region}:*:function:${self:service}-${opt:stage}-*
  - Effect: "Allow"
    Action:
      - "ses:SendEmail"
      - "ses:SendEmailRaw"
    Resource: "arn:aws:ses:eu-west-1:01234567891234:identity/noreply@example.com"

然后您将使用以下命令从命令行执行脚本:

BULK INSERT ZIPCodes 
FROM  '$(filepath)' 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)
end

该示例的重要部分是-v参数:

sqlcmd -b -S SERVER\INSTANCEHERE -E -i "PATH\FILENAMEHERE.Sql" -v FilePath = "e:\5-digit Commercial.csv" -s "|"

答案 3 :(得分:0)

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;