web-dev-qa-db-fra.com

Insertion en bloc à l'aide d'une procédure stockée

J'ai une requête qui fonctionne bien:

BULK INSERT ZIPCodes 
FROM  'e:\5-digit Commercial.csv' 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)

mais maintenant je veux créer une procédure stockée pour cela.

J'ai écrit ci-dessous le code pour faire sa procédure stockée:

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

mais son erreur montrant:

Msg 102, Niveau 15, Etat 1, Procédure InsertZipCode, Line 6 Syntaxe incorrecte près de '@filepath'.

Msg 319, Niveau 15, Etat 1, Procédure InsertZipCode, Line 7 Syntaxe incorrecte près du mot clé 'avec'. Si ce instruction est une table commune expression, une clause xmlnamespaces ou une clause de contexte de suivi de changement, le déclaration précédente doit être terminée avec un point-virgule.

Dites-moi ce qui ne va pas et ce que je peux faire pour que cela fonctionne dans une procédure stockée.

Merci

28
Dr. Rajesh Rolen

Le code de votre procédure stockée n’est pas mauvais. L’important est que la commande BULK INSERT ne peut pas accepter un nom de fichier en tant que variable.

Cela fonctionne:

BULK INSERT ZIPCodes 
FROM  'e:\5-digit Commercial.csv' 
WITH 

mais cela ne marche jamais - dans un proc stocké ou non:

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

BULK INSERT ZIPCodes 
FROM @filename
WITH 

Donc, vous ne pouvez pas le faire de cette façon, malheureusement. Vous pouvez envisager de construire votre instruction BULK INSERT sous forme de chaîne (avec un nom de fichier fixe), puis de l'exécuter sous forme de code SQL dynamique, mais je ne vois pas vraiment d'autre solution.

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
37
marc_s

Vous venez de l'essayer, je pense que vous devez télécharger ce fichier CSV directement sur le lecteur 'E'. Je pense que pour cela, vous devez avoir les droits d’administrateur ou demander à un administrateur de la base de données.

create procedure dbo.InsertZipCode
AS
BEGIN
SET NOCOUNT ON;
 BULK
   INSERT ZIPCodes from 'e:\5-digit Commercial.csv'
WITH
(
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\n'
)
END
0
Dhanya Raj
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;
0
Meera

Il existe une alternative au SQL dynamique si vous avez accès au fichier exe SQLCmd.

L'utilitaire SqlCmd vous permet de transmettre des variables de remplacement de chaîne à l'aide de l'argument -v.

Vous pouvez utiliser une variable de modèle nommée "chemin de fichier" qui sera remplacée lorsque vous exécuterez le script via la ligne de commande.

Le script SQL ressemblerait à ceci:

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

Vous exécuteriez ensuite le script à partir d'une ligne de commande en utilisant quelque chose comme ce qui suit:

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

La partie importante de l'exemple est l'argument -v:

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