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
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
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
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;
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"