Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 对存储在ntext列中的csv数据执行查询_Sql Server_Sql Server 2005_Tsql_Csv_Openrowset - Fatal编程技术网

Sql server 对存储在ntext列中的csv数据执行查询

Sql server 对存储在ntext列中的csv数据执行查询,sql-server,sql-server-2005,tsql,csv,openrowset,Sql Server,Sql Server 2005,Tsql,Csv,Openrowset,假设CSV导出的原始文本和关联的时间戳存储在数据库中,其中一条记录相当于一次导出 是否有人可以对存储在该字段中的CSV文件执行查询,而无需创建与数据库的第二个连接或将数据导出到文件,然后使用CSV文本驱动程序重新打开该文件 假设: 1) 无法将物理文件写入解决方案中的服务器 2) 无法使用OPENROWSET(服务器、用户名和密码更改)再次连接到服务器 3) 它必须是100%SQL解决方案-必须能够作为SP运行 4) 您一次只需要处理一条记录-解决方案不需要考虑从数据库中存储的多个csv文件中进

假设CSV导出的原始文本和关联的时间戳存储在数据库中,其中一条记录相当于一次导出

是否有人可以对存储在该字段中的CSV文件执行查询,而无需创建与数据库的第二个连接或将数据导出到文件,然后使用CSV文本驱动程序重新打开该文件

假设:

1) 无法将物理文件写入解决方案中的服务器

2) 无法使用OPENROWSET(服务器、用户名和密码更改)再次连接到服务器

3) 它必须是100%SQL解决方案-必须能够作为SP运行


4) 您一次只需要处理一条记录-解决方案不需要考虑从数据库中存储的多个csv文件中进行选择。

您可以设置一系列用户定义的函数,这些函数可以解析整个列。它可能会很慢,而且根本不会很健壮

例如(没有真正的错误检查等,只进行了最低限度的测试):

如果对象ID('dbo.Test\u CSV\u Search')不为空
删除表dbo.Test\u CSV\u搜索
去
创建表dbo.Test\u CSV\u搜索
(
我的id INT标识不为空,
txt VARCHAR(最大值)不为空,
约束PK\u测试\u CSV\u搜索主键群集(my\u id)
)
去
在dbo.Test_CSV_搜索(txt)中插入值('11,12,13,14,15,16
21,22, 23,24, 25,26
31,22,33,34,35,36')
去
如果对象ID(“dbo.Get\u CSV\u行”)不为空
删除函数dbo.Get\u CSV\u行
去
创建函数dbo.Get\u CSV\u行
(@my_id INT、@col_num SMALLINT、@search_value VARCHAR(100))
返回@results表(row_num INT,row_txt VARCHAR(MAX))
像
开始
声明
@csv_txt VARCHAR(最大值),
@全行VARCHAR(最大值),
@开始位置INT,
@结束位置INT,
@col_txt VARCHAR(100),
@斯莫林特街,
@行_startint,
@行_endint,
@行数INT
从dbo.Test\u csv\u搜索中选择@csv\u txt=txt+CHAR(10),其中my\u id=@my\u id
选择
@行_start=1,
@cur_col=1,
@开始位置=1,
@行数=1
而(CHARINDEX(CHAR(10),@csv\u txt,@line\u start)>0)
开始
选择
@line_end=CHARINDEX(CHAR(10),@csv_txt,@line_start),
@end_pos=CHARINDEX(“,”,@csv_txt,@start_pos)
而(@cur_col<@col_num)
开始
设置@start\u pos=@end\u pos+1
设置@end_pos=CHARINDEX(“,”,@csv_txt,@start_pos)
设置@cur\u col=@cur\u col+1
终止
IF(RTRIM(LTRIM(子字符串(@csv_txt,@start_pos,@end_pos-@start_pos)))=@search_值)
开始
插入@results(row_num,row_txt)值(@row_num,RTRIM(LTRIM(子字符串(@csv_txt,@line_-start,@line_-end-@line_-start)))
终止
选择
@行开始=@行结束+1,
@开始位置=@line\u结束+1,
@cur_col=1,
@行数=@行数+1
终止
回来
终止
去
从dbo.Get_CSV_行中选择*

我的解决方案是创建一个UDF,将CSV数据解析为一个表变量。然后,在SP中检索CSV,将其传递给UDF,然后对表变量运行查询

首先,创建一个UDF,从CSV值返回一个表(使用CHAR(13)确定新行,可能需要修改以处理数据):

然后对该输出运行查询:

select * from dbo.fnParseCsv('123,val1' + char(13) + '456,val2' + CHAR(13) + '789,val3', ',')

什么构成“执行查询”?CSV数据是否具有相同的结构?该结构是预定义的吗?@PK CSV数据将具有相同的结构,并且是预定义的@Tom H.假设它只需要处理简单的选择(没有子查询,也绝对没有更改csv数据中的记录),csv文件在引用字段中是否有任何嵌入的逗号?@Martin Yes-好问题。CSV数据包括带引号的字段,其中嵌入逗号来处理地址,这将使试图通过UDF处理地址变得更加痛苦。
CREATE FUNCTION [dbo].[fnParseCSV] (@InputString NVARCHAR(MAX), @Delimiter NCHAR(1) = ',')  
RETURNS @tbl TABLE (ID int, Val NVARCHAR(64)) AS 
BEGIN
    declare @singleLine nvarchar(max)
    declare @id int
    declare @val varchar(64)

    WHILE LEN(@InputString) > 0 BEGIN
        IF CHARINDEX(char(13), @InputString) > 0 BEGIN
            SELECT  @singleLine = SUBSTRING(@InputString, 1, CHARINDEX(char(13), @InputString) - 1)
            IF CHARINDEX(@Delimiter, @singleline) > 0 BEGIN
                SELECT  @id = convert(int, SUBSTRING(@singleline, 1, CHARINDEX(@Delimiter, @singleline) - 1))
                SELECT @val = RIGHT(@singleline, LEN(@singleline) - CHARINDEX(@Delimiter, @singleline) )
                INSERT INTO @tbl (id, val) values (@id, @val)
            END

            SELECT @InputString = RIGHT(@InputString, LEN(@InputString) - CHARINDEX(char(13), @InputString) )
        END
        ELSE 
        BEGIN
            IF CHARINDEX(@Delimiter, @inputString) > 0 
            BEGIN
                SELECT  @id = convert(int, SUBSTRING(@inputString, 1, CHARINDEX(@Delimiter, @inputString) - 1))
                SELECT @val = RIGHT(@inputString, LEN(@inputString) - CHARINDEX(@Delimiter, @inputString) )
                INSERT INTO @tbl (id, val) values (@id, @val)
            END
            set @inputString = ''
        END
    END
    RETURN
END
select * from dbo.fnParseCsv('123,val1' + char(13) + '456,val2' + CHAR(13) + '789,val3', ',')