2017-06-13 62 views
1

我曾經使用批量插入命令來轉換Csv文件int table.Resently我保存CSV文件作爲VarBinary值在SQL Server.Now我可以通過使用CAST和CONVERT函數將它壓縮到Varchar從Varbinary文件中獲取數據。如何將字符串傳遞給批量插入而不是文件?

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

請幫me.Is有任何方式或:但現在我有一個問題,我不能轉換爲使用散裝insert.Can任何一個可以幫助我的CSV包含內容表這個字符串的Varchar我 示例代碼下面給出替代將數據從csv字符串插入到表中。

回答

0

編輯:允許多個字符分隔符

這就是我解決它的方法。它涉及:

  • 爲劈裂換行符甲表值函數(xftSplit)(CHAR(10))插入表線
  • 標量函數(fSubstrNth)用於提取線的第n個字段,給定的一個分離器
  • 標量函數(fPatIndexMulti)用於找到隔板
  • (可選)替代Right函數的第n個索引到接受負值
  • 最後,一些特定的代碼來解決方案中的使用,因爲, SQL不是(從動態列的功能,換句話說,你不能SELECT)llow動態表函數定義現在

,對於代碼片段:

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 

Xright確定

-- ============================================= 
-- 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 

具體代碼

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 

注意的是:

  • fSubstrNth接收第n個字段以從線
  • xftSplit提取接收包含要批量從字符串(無論源)和char(10)作爲\n分離器的變量,但也可能是其他任何東西
  • 該查詢可以是任何其他。這意味着它可以存儲在程序,表格功能,視圖等中。您可以提取部分或全部領域,在您希望的順序和過程,但是你想
  • 如果在存儲過程中使用,你可以創建創建與動態列裝載字符串的查詢和臨時表的一個通用的方法,但是你要撥打電話到另一個程序使用的數據或創建相同的程序像上面特定的查詢(這將使其成爲非通用的,只是更多的可重複使用)
相關問題