SQL Server从表中读取csv二进制文件

时间:2014-05-16 13:07:36

标签: sql-server file csv blob

我目前将csv格式的文件存储在磁盘上,然后像这样查询:

SELECT *
FROM OPENROWSET(BULK 'C:\myfile.csv',
    FORMATFILE = 'C\format.fmt',
    FIRSTROW = 2) AS rs

其中format.fmt是csv文件中列的已定义格式。这非常有效。 但我有兴趣将文件存储在SQL Server表中,而不是将它们存储在磁盘上。 因此,当具有VARBINARY(MAX)数据类型列时。我如何查询它们?

如果我有一张表:

CREATE TABLE FileTable
(
    [FileName] NVARCHAR(256)
    ,[File] VARBINARY(MAX)
)

有一行'myfile.csv', '0x427574696B3B44616....'

如何将该文件内容读入临时表?例如?

2 个答案:

答案 0 :(得分:2)

如果你真的需要使用varbinary数据,你可以把它转换回nvarchar:

DECLARE @bin VARBINARY(MAX)
SET @bin = 0x5468697320697320612074657374

SELECT CAST(@bin as VARCHAR(MAX))
-- gives This is a test

一旦进入该格式,就可以使用拆分功能将其转换为表格。不要问我为什么SQL Server中没有内置的拆分功能,因为它是一个非常明显的疏忽,但没有。因此,请使用以下代码创建您自己的代码:

CREATE FUNCTION [dbo].[fn_splitDelimitedToTable] ( @delimiter varchar(3), @StringInput VARCHAR(8000) )
RETURNS @OutputTable TABLE ([String] VARCHAR(100), [Hierarchy] int )
AS
BEGIN

    DECLARE @String    VARCHAR(100)
    DECLARE @row int = 0

    WHILE LEN(@StringInput) > 0
    BEGIN
        SET @row = @row + 1
        SET @String      = LEFT(@StringInput, 
                                ISNULL(NULLIF(CHARINDEX(@delimiter, @StringInput) - 1, -1),
                                LEN(@StringInput)))
        SET @StringInput = SUBSTRING(@StringInput,
                                     ISNULL(NULLIF(CHARINDEX(@delimiter, @StringInput), 0),
                                     LEN(@StringInput)) + 1, LEN(@StringInput))

        INSERT INTO @OutputTable ( [String], [Hierarchy] )
        VALUES ( @String, @row )
    END

    RETURN
END

把它们放在一起:

select CAST('one,two,three' as VARBINARY)
-- gives 0x6F6E652C74776F2C7468726565

DECLARE @bin VARBINARY(MAX)
SET @bin = 0x6F6E652C74776F2C7468726565

select * from fn_splitDelimitedToTable(',', CAST(@bin as VARCHAR(MAX)))

给出了这个结果:

string hierarchy
================
one    1
two    2
three  3

当然,如果您愿意,可以将结果导入临时表:

select * into #myTempTable
from fn_splitDelimitedToTable(',', CAST(@bin as VARCHAR(MAX)))

答案 1 :(得分:0)

  

如果您有CSV数据,为什么不将其导入数据库呢?

您也可以使用BULK INSERT执行此操作,如this question

假设您已创建一个具有正确格式的表格以将数据导入(例如“MyImportTable”),可以使用以下内容:

BULK INSERT MyImportTable
FROM 'C:\myfile.csv'
WITH (DATAFILETYPE='char',
      FIRSTROW = 2,
      FORMATFILE = 'C\format.fmt');

编辑1:

将数据导入数据库后,您现在可以直接查询表格,并完全避免使用CSV:

 SELECT *
   FROM MyImportTable

不再需要引用原始CSV,您可以删除/存档原始CSV。

编辑2:

如果您已启用xp_cmdshell,并且您具有相应的权限,则可以使用以下命令从SQL中删除该文件:

xp_cmdshell 'del c:\myfile.csv'

最后,如果要启用xp_cmdshell,请使用以下命令:

exec sp_configure
go
exec sp_configure 'xp_cmdshell', 1
go
reconfigure
go