web-dev-qa-db-de.com

Masseneinfügung mit gespeicherter Prozedur

Ich habe eine Abfrage, die gut funktioniert:

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

aber jetzt möchte ich eine gespeicherte Prozedur dafür erstellen.

Ich habe folgenden Code geschrieben, um seine gespeicherte Prozedur zu erstellen:

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

aber es zeigt einen Fehler:

Meldung 102, Ebene 15, Status 1, Verfahren InsertZipCode, Zeile 6 Falsche Syntax in der Nähe von '@filepath'.

Meldung 319, Ebene 15, Status 1, Verfahren InsertZipCode, Zeile 7 Falsche Syntax in der Nähe des Stichworts "mit". Wenn dies Anweisung ist eine gemeinsame Tabelle Ausdruck, eine xmlnamespaces-Klausel oder eine Änderungsverfolgungskontextklausel, die vorherige Anweisung muss beendet werden mit einem Semikolon.

Bitte sagen Sie mir, was ich falsch mache und was ich tun kann, damit es in einer gespeicherten Prozedur funktioniert.

Vielen Dank

28

Ihr Code für gespeicherte Prozeduren ist in Ordnung. Der Punkt ist: Der Befehl BULK INSERT kann einen Dateinamen nicht als Variable akzeptieren.

Das funktioniert:

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

aber das funktioniert nie - innerhalb einer gespeicherten proc oder nicht:

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

BULK INSERT ZIPCodes 
FROM @filename
WITH 

Also kann man das leider nicht so machen. Sie könnten die BULK INSERT-Anweisung als String (mit einem festen Dateinamen) aufbauen und dann als dynamisches SQL ausführen - aber ich sehe keine andere Lösung.

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

Probieren Sie es einfach aus, ich denke, Sie müssen diese CSV-Datei direkt auf das Laufwerk "E" hochladen. Dafür brauche ich Administratorrechte, denke ich, oder frage jemanden, der sich in der Datenbankverwaltung befindet.

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

Es gibt eine Alternative zu Dynamic SQL, wenn Sie Zugriff auf das SQLCmd-Exe haben.

Mit dem Dienstprogramm SqlCmd können Sie Zeichenfolgenersetzungsvariablen mit dem Argument -v übergeben.

Sie können eine Vorlagenvariable namens "Dateipfad" verwenden, die ersetzt wird, wenn Sie das Skript über die Cmdline ausführen.

Das SQL-Skript würde folgendermaßen aussehen:

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

Sie führen das Skript dann von einer Befehlszeile aus wie folgt aus:

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

Der wichtige Teil des Beispiels ist das Argument -v:

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