拆分文本字符串 - 变量与列

时间:2017-06-17 17:53:13

标签: sql-server sql-server-2012

我运行这件作品

--
-----------
DECLARE @QCSteps varchar(max)
SET @QCSteps = '42 - step 0;#43 - step 1;#44 - step 2;#45 - step 3'

DECLARE @separator varchar(max)
SET @separator = ';#'

DECLARE @Splited table(id int IDENTITY(1,1), item varchar(max))

SET @QCSteps = REPLACE(@QCSteps, @separator, ''' UNION ALL SELECT ''')
SET @QCSteps = ' SELECT  ''' + @QCSteps + '''  ' 

INSERT INTO @Splited
EXEC(@QCSteps)

SELECT * FROM @Splited

它产生了这个

----
---------------
[text string nicely split in 4][1]

如何从现有表格列中运行此阅读文本字符串?

3 个答案:

答案 0 :(得分:1)

你不能使用这种方法。

你需要CROSS APPLY到一个表值函数和TSQL表值函数不能执行动态SQL(CLR可以但这将是愚蠢的,因为在CLR中拆分字符串无论如何都像这里一样{{ {3}})。

您需要使用拆分功能的不同实现。例如,来自http://dataeducation.com/sqlclr-string-splitting-part-2-even-faster-even-more-scalable/

的一个

答案 1 :(得分:1)

您可以尝试使用以下解决方案将原始字符串转换为XML,然后使用nodes()方法将XML数据分解为单独的项目:

public class EmailController extends Controller {
private myservice.MyEnvironment env;

@Inject
public UserFormHandler(myservice.MyEnvironment) {
    this.env = env;
}

结果: enter image description here

注意:如果原始字符串包含一些XML保留字符(例如SELECT x.ID, y.XmlCol.value('(text())[1]', 'NVARCHAR(256)') AS ItemInnerText FROM ( SELECT t.ID, CONVERT(XML, N'<root><i>' + REPLACE(t.QCSteps, N';#', N'</i><i>') + '</i></root>') AS QCStepsAsXML FROM ( SELECT 1, '42 - step 0;#43 - step 1;#44 - step 2;#45 - step 3' UNION ALL SELECT 2, 'AA - step 0;#BB - step 1' ) AS t(ID, QCSteps) -- Replace FROM (...) AS t(ID, QCSteps) with FROM dbo.Table1 AS t ) AS x CROSS APPLY x.QCStepsAsXML.nodes(N'root/i') AS y(XmlCol) ),此解决方案将生成异常。如果这是你的情况,请告诉我。

答案 2 :(得分:0)

这是一个XML安全的内联版本。

您可能还会注意到我们也会返回项目序列。这是可选的,但我发现它有很多用途。

示例

Declare @YourTable table (ID int,SomeCol varchar(max))
Insert Into @YourTable values
  (1,'42 - step 0;#43 - step 1;#44 - step 2;#45 - step 3')

Select A.ID
      ,B.*
From  @YourTable A
Cross Apply (
                Select RetSeq = Row_Number() over (Order By (Select null))
                      ,RetVal = LTrim(RTrim(P2.i.value('(./text())[1]', 'varchar(max)')))
                From  (Select x = Cast('<x>' + replace((Select replace(A.SomeCol,';#','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as P1
                Cross Apply x.nodes('x') AS P2(i)
            ) B

<强>返回

ID  RetSeq  RetVal
1   1       42 - step 0
1   2       43 - step 1
1   3       44 - step 2
1   4       45 - step 3