光标枢轴分割功能的替代方案?

时间:2016-02-03 00:16:16

标签: sql-server sql-server-2012 etl

所以我正在创建一个存储过程,其最终目标是动态ETL解决方案。我的公司处理很多第三方数据,而且我经常不知道列的数量,数据类型,数据的格式等等......因此,我把一些带有动态的临时表放在一起sql和bulk insert语句将数据导入SQL Server。目前,数据作为单个列nvarchar字段,以制表符或管道分隔,并且每个txt或csv文件通常超过100k行。上述csv / txt格式的一个例子如下:

RawSingleLine
9XX01 No Cancelled Inadvertent Approval 1/12/2015 432115.2 99   
480X1 No Cancelled Pending Processing 1/7/2014 5060 27.5    

我目前的解决方案是使用游标和下面的Split函数循环遍历所有单行,拆分它们,转动它们,然后插入我的一个动态临时表中。但是,我想避免使用游标,因为它们很昂贵,并且首选基于集合的操作。

CREATE FUNCTION [dbo].[udf_Split]
(
    @String NVARCHAR(4000),
    @Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
    WITH Split(stpos,endpos)
    AS(
        SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
        UNION ALL
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
            FROM Split
            WHERE endpos > 0
    )
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
        'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
    FROM Split
)

有没有办法在没有光标的情况下实现我想要的东西?

1 个答案:

答案 0 :(得分:0)

免责声明:我是该项目的所有者Eval SQL.NET

此解决方案允许在大约2-3秒内拆分和旋转100k行。 Eval SQL.NET允许在T-SQL中执行C#代码。

-- CREATE a big string with all the rows (100,000 rows)
DECLARE @s VARCHAR(MAX) = ''
SET @s = ( SELECT TOP ( 100000 )
                    RawSingleLine + CHAR(13) + CHAR(10)
           FROM     Import
FOR XML PATH('') ,
        TYPE
         ).value('text()[1]', 'varchar(max)')

-- Use C# Syntax to split the text. Use Regex.Split if necessary.
DECLARE @sqlnet SQLNET = SQLNET::New('
var rows = s.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
return rows.Select(x => x.Split('' '')).ToList()
').ValueString('s', @s).AutoDispose()

EXEC dbo.SQLNET_EvalResultSet @sqlnet