2017-06-13 65 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分离器的变量,但也可能是其他任何东西
  • 该查询可以是任何其他。这意味着它可以存储在程序,表格功能,视图等中。您可以提取部分或全部领域,在您希望的顺序和过程,但是你想
  • 如果在存储过程中使用,你可以创建创建与动态列装载字符串的查询和临时表的一个通用的方法,但是你要拨打电话到另一个程序使用的数据或创建相同的程序像上面特定的查询(这将使其成为非通用的,只是更多的可重复使用)
相关问题