4

我有一个表格,其中一列包含以下数据:

abc,2,2,34,5,3,2,34,32,2,3,2,2
def,2,2,34,5,3,2,34,32,2,3,2,2

我想获取这些数据并将其插入到另一个表中,使用逗号作为分隔符,就像您可以指定FIELDTERMINATORinBULK INSERT语句一样。

有没有办法使用 T-SQL 做到这一点?

4

3 回答 3

3

您需要使用Split函数将字符串拆分为表变量,然后将这些值插入表中。

那里有大量的拆分函数,具有各种优缺点以及各种数量的参数等等。

这是我非常喜欢的一个- 做得非常好,解释清楚。

使用该功能,您应该可以轻松地将列转换为其他表的单独条目。

于 2012-05-10T20:28:14.650 回答
3

我不确定在 T-SQL 中是否有任何直接的方法,但如果你想使用批量插入,你可以使用sqlcmd导出到 CSV 文件,然后使用批量插入将文件导入服务器。

创建一个dbo.SplitFunctionm,你可以参考这里split string into multiple record 有很多很好的例子。

如果您想作为批处理执行,您可以执行sqlcmd并“批量插入”

sqlcmd -S MyServer -d myDB -E -Q "select dbo.Split(col1) from SomeTable" 
       -o "MyData.csv" -h-1 -s"," -w 700

-s"," sets the column seperator to 

bulk insert destTable
from "MyData.csv"
with 
(
  FIELDTERMINATOR = ',',
  ROWTERMINATOR = '\n'
)

否则,您可以直接在 T-SQL 中进行操作,但前提是您具有相同的列定义标识。

 INSERT INTO DestinationTable
 SELECT dbo.Split(col1) FROM SomeTable
于 2012-05-10T20:37:21.760 回答
0

编辑:允许多个字符分隔符

这就是我解决它的方法,使用两个函数来拆分成列(如果您还想要一个更完整的行拆分解决方案,请参阅我的另一篇文章)。它涉及:

  • fSubstrNth给定分隔符,用于提取行的第 n 个字段的标量函数 ( )
  • fPatIndexMulti用于查找分隔符的第 n 个索引的标量函数 ( )
  • (可选)Right接受负值的替代函数
  • 最后,在您的解决方案中使用一些特定的代码,因为 SQL 不允许动态表函数定义(换句话说,您不能SELECT使用具有动态列的函数)

现在,对于代码片段:

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('%'+@Find+'%',@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

-- =============================================
-- 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(table.datacolumn,',',1),
     field2 = dbo.fSubstrNth(table.datacolumn,',',2),
     anothercolumn = 'set your query as you would normally do',
     field3 = (CASE dbo.fSubstrNth(table.datacolumn,',',3) WHEN 'C' THEN 1 ELSE 0 END)
FROM table

注意:

  • fSubstrNth接收要从“数据列”中提取的第 n 个字段
  • 查询可以与任何其他查询一样。这意味着它可以存储在过程、表格函数、视图等中。您可以按您希望的任何顺序提取部分或全部字段,并按您希望的方式进行处理
  • 如果在存储过程中使用,您可以创建一个通用的方法来创建一个查询和临时表,以加载带有动态列的字符串,但是您必须调用另一个过程才能使用数据或创建一个特定的查询,如上面相同的过程(这将使它成为非通用的,只是更可重用)
于 2017-07-18T20:33:16.137 回答