解析逗号分隔列以插入表中

时间:2013-12-17 18:43:03

标签: sql-server tsql

我有一个表格,其中列如下所示:

Column 0
2013-11-27 13:11:00,1XRTT,DATA,East Michigan,Region 2,East Michigan_PORT HURON_CL#17,LNS1,2436,DE60XC049,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,76,0,0,0,0,0,0,0,41,35,0,2.59444444444444444444444444444444444444,0,76,0,0,0,168,168,,,,,,,,,,,,,,,,,,,,,,,,,155.666666666666666666666666666666666667,0,0,0,0,0,3,0,104,0,0,0,150,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0

我想将它解析为另一个表,其中包含每个分隔符的列。我已经创建了插入表,但是如何将其解析为新表?

根据Mate的评论,我做了这个

创建了这样的函数:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SplitString_Using_CTE_Charindex]')
AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
    DROP FUNCTION [dbo].[SplitString_Using_CTE_Charindex]
GO

CREATE FUNCTION SplitString_Using_CTE_Charindex (@csv_str VARCHAR(8000),@delimiter varchar(20) )
 RETURNS @splittable TABLE (id int identity(1,1), csvvalues VARCHAR(8000) )
AS
BEGIN  

-- Check for NULL string or empty sting
    IF  (LEN(@csv_str) < 1 OR @csv_str IS NULL)
    BEGIN
        RETURN
    END

    ; WITH csvtbl(i,j)
    AS
    (
        SELECT i=1, j= CHARINDEX(@delimiter,@csv_str+@delimiter) 

        UNION ALL 

        SELECT i=j+1, j=CHARINDEX(@delimiter,@csv_str+@delimiter,j+1)
        FROM csvtbl
        WHERE CHARINDEX(@delimiter,@csv_str+@delimiter,j+1) <> 0
    )   

    INSERT  INTO @splittable  ( csvvalues)
    SELECT  SUBSTRING(@csv_str,i,j-i)
    FROM    csvtbl 

    RETURN
END  

GO

然后跑了这个:

DECLARE @csv_str VARCHAR(8000)
        ,@delimiter VARCHAR(20)
SET @csv_str = (select * from testimport);

SET @delimiter =','

SELECT * FROM dbo.SplitString_Using_Charindex(@csv_str,@delimiter)

然后我得到了这个:

Msg 512, Level 16, State 1, Line 3
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

我在查询中也做了前1名但是得到了这个:

Msg 530, Level 16, State 1, Line 43
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.

2 个答案:

答案 0 :(得分:0)

有两件事是错的。首先,如果要将查询结果分配给varchar变量,则需要保证查询只返回一个varchar或可以隐式转换的值。现在你正在说“把这个结果集大概长到几行并将其填充到一个字符串中”。您应该在查询中添加前1,但这不是一个长期解决方案,只是为了测试。最终,您需要使用游标迭代结果或重新设计函数以接受结果表作为输入,从而实现此过程。如果你想要扩展,那么后者将是最好的。

第二个问题是您不能将该函数视为要从中选择的表。这就是它给你第二个错误的原因。这就像你试图从计数(*)中选择*,这实际上没有意义。我建议将其更改为存储过程,这样您就可以创建一个结果表并通过调用exec中的内容来插入它,例如exec SplitString_Using_Charindex @csv_str,@ delimiter

答案 1 :(得分:0)

如果您有权访问文件系统,则可以使用SQL Server的BCP工具将数据转储到平面文件,然后以逗号分隔的方式将其读回。正如您可能已经想到的那样,SQL不是一个很好的文本解析工具。

bcp MySourceTable out C:\tabledump.txt -c -T


BULK INSERT MyDestinationTable
FROM 'C:\tabledump.txt'
WITH (
   DATAFILETYPE='char',
   FIELDTERMINATOR=','
);