2017-06-13 2 views
1

Ich benutze Bulk-Insert-Befehl, um eine Csv-Datei int-Tabelle zu konvertieren.Residently habe ich eine CSV-Datei als VarBinary Wert in SQL-Server.Now kann ich Daten aus Varbinary-Datei durch Typecasting es nach Varchar mit CAST und CONVERT-Funktionen. aber jetzt habe ich ein Problem habe ich dieses Varchar String Tabelle mit csv Inhalt konvertieren kann nicht Masse mit insert.Can einem helfen mir Mein Beispiel-Code ist unten angegeben:Wie String an Bulk übergeben anstelle von Datei einfügen?

[email protected] contains varchar value of CSV file content. 
SET @sql = 'BULK INSERT TempCsv 
FROM ''' + @String + ''' 
WITH 
(
    FIRSTROW = 2, 
    FIELDTERMINATOR = '','', 
    ROWTERMINATOR = ''\n'', 
    TABLOCK 
)' 

Bitte helfen me.Is es eine Möglichkeit, oder Alternative zum Einfügen von Daten aus CSV-String in Tabelle.

Antwort

0

EDIT: erlauben mehrere char Separatoren

Dies ist, wie ich es gelöst. Sie beinhaltet:

  • A Tabellenwertfunktion (xftSplit) für spliting Zeilenumbrüche (char (10)) in den Tabellenzeilen
  • A Skalarfunktion (fSubstrNth) für das n-ten Halbbild eines Zeile Extrahieren ein Separator
  • Eine Skalarfunktion (fPatIndexMulti) zum Auffinden des n-ten Index des Separators
  • (Optional) alternativer Right Funktion gegeben negative Werte
  • schließlich einiger spezifischer Code zu akzeptieren, in Ihrer Lösung zu verwenden, da SQL tut das nicht llow dynamische Tabellenfunktionsdefinitionen (in anderen Worten, man kann nicht SELECT aus einer Funktion mit dynamischen Spalten)

Nun, für den Code-Schnipsel:

xftSplit

-- ============================================= 
-- Author:  Bernardo A. Dal Corno 
-- Create date: 15/07/2014 
-- Description: Quebra valores a partir de caracteres e retorna lista em tabela 
-- ============================================= 
CREATE FUNCTION [dbo].[xftSplit] 
(
    @Texto varchar(max), 
    @Splitter varchar(3) 
) 
RETURNS 
@Lista TABLE 
(
    ValoresQuebrados varchar(8000) 
) 
AS 
BEGIN 
DECLARE @Pos Smallint 

    While len(@Texto)>0 BEGIN 
    SET @Pos = Patindex('%'[email protected]+'%',@Texto) 

    IF @Pos > 0 BEGIN 
     INSERT INTO @Lista 
     SELECT left(@Texto, @Pos-1) 

     SET @Texto = right(@Texto, len(@Texto)[email protected]) 
    END 
    ELSE BEGIN 
     INSERT INTO @Lista 
     SELECT @Texto 

     SET @Texto = '' 
    END 
    End 

    RETURN 
END 

fSubstrNth

-- ============================================= 
-- Author:  Bernardo A. Dal Corno 
-- Create date: 18/07/2017 
-- Description: substring com 2 PatIndex limitando inicio e fim 
-- ============================================= 
CREATE FUNCTION fSubstrNth 
(
    @Text varchar(max), 
    @Sep varchar(3), 
    @N int --Nth campo 
) 
RETURNS varchar(max) 
AS 
BEGIN 
    DECLARE @Result varchar(max) 

    IF @N<1 RETURN '' 
    IF @N=1 
    SET @Result = substring(@Text, 1, dbo.fPatIndexMulti(@Sep,@Text,1)-1) 
    ELSE 
    SET @Result = substring(@Text, dbo.fPatIndexMulti(@Sep,@Text,@N-1)+LEN(@Sep), CASE WHEN dbo.fPatIndexMulti(@Sep,@Text,@N)>0 THEN dbo.fPatIndexMulti(@Sep,@Text,@N)-dbo.fPatIndexMulti(@Sep,@Text,@N-1)-LEN(@Sep) ELSE LEN(@Text)+1 END) 

    RETURN @Result 
END 

fPatIndexMulti

-- ============================================= 
-- Author:  Bernardo A. Dal Corno 
-- Create date: 17/07/2017 
-- Description: recursive patIndex 
-- ============================================= 
CREATE FUNCTION [dbo].[fPatIndexMulti] 
(
    @Find varchar(max), 
    @In varchar(max), 
    @N tinyint 
) 
RETURNS int 
AS 
BEGIN 
    DECLARE @lenFind int, @Result int, @Texto varchar(max), @index int 
    DECLARE @i tinyint=1 

    SET @lenFind = LEN(@Find)-1 
    SET @Result = 0 
    SET @Texto = @In 
    WHILE (@i <= @N) BEGIN 
    SET @index = patindex('%'[email protected]+'%',@Texto) 
     IF @index = 0 RETURN 0 
    SET @Result = @Result + @index 
    SET @Texto = dbo.xRight(@Texto, (@index + @lenFind)*-1) 

    SET @i = @i + 1 
    END 
    SET @Result = @Result + @lenFind*(@i-2) 

    RETURN @Result 
END 

xRechts

-- ============================================= 
-- Author:  Bernardo A. Dal Corno 
-- Create date: 06/01/2015 
-- Description: Right inverso (para nros < 0) 
-- ============================================= 
CREATE FUNCTION [dbo].[xRight] 
(
    @Texto varchar(8000), 
    @Qntd int 
) 
RETURNS varchar(8000) 
AS 
BEGIN 
    DECLARE @Result varchar(8000) 

    IF (Len(@Texto) = 0) OR (@Qntd = 0) 
    SET @Result = '' 
    ELSE IF (@Qntd > 0) 
     SET @Result = Right(@Texto, @Qntd) 
    ELSE IF (@Qntd < 0) 
    SET @Result = Right(@Texto, Len(@Texto) + @Qntd) 

    RETURN @Result 
END 

spezifischen Code

SELECT 
    acolumn = 'any value', 
    field1 = dbo.fSubstrNth(line,',',1), 
    field2 = dbo.fSubstrNth(line,',',2), 
    anothercolumn = 'set your query as you would normally do', 
    field3 = (CASE dbo.fSubstrNth(line,',',3) WHEN 'C' THEN 1 ELSE 0 END) 
FROM (
    SELECT line = ValoresQuebrados FROM dbo.xftSplit(@StringVariable, char(10)) 
) lines 

Beachten Sie, dass:

  • fSubstrNth empfängt die n-ten Feld von der Linie zu extrahieren
  • xftSplit erhält eine Variable, die die Zeichenfolge, die Sie auf Masse möchten enthält (unabhängig von der Quelle) und eine char(10) als Splitter von \n, aber es könnte sein, alles andere
  • Die Abfrage kann wie jede andere auch sein. Dies bedeutet, dass es in einer Prozedur, einer Tabellenfunktion, einer Ansicht usw. gespeichert werden kann.Sie können einige oder alle Felder in beliebiger Reihenfolge extrahieren und beliebig weiterverarbeiten
  • Wenn Sie in einer gespeicherten Prozedur verwendet werden, können Sie eine generische Methode zum Erstellen einer Abfrage und einer temporären Tabelle erstellen, die die Zeichenfolge mit dynamischen Spalten lädt. Sie müssen jedoch eine andere Prozedur aufrufen, um die Daten zu verwenden ODER eine spezifische Abfrage wie oben in derselben Prozedur erstellen (was sie zu einer nicht generischen, einfach wiederverwendbaren Instanz macht)
Verwandte Themen