SQL字符串函数

时间:2014-02-15 22:21:05

标签: sql sql-server string sql-server-2008 substring

这是一个我花费太多时间的问题。

我正在传递一个字符串

@OrderString varchar(255) = '1=1;|2=|3=|4=1;|5=|'

第一个数字是我要订购的商品我会在@ItemNum中将=保存为@ItemQuat之后将其保存为= 。数量可以是1到1000之间的任何数量。如果订购零,那么它只是项目编号和--Obviously this won't work because it will always pull 1 regardless if the amount ordered is 0 set @ItemNum = substring(@OrderString, 1, charindex('=', @OrderString, 1)-1) --This is currently wrong too because its pulling the quant for item 1 set @ItemQuat = substring(@OrderString, charindex('=',@OrderString,1)+1, charindex('|',@OrderString,1)-charindex('=',@OrderString,1)-1)

问题是如何动态提取这些值?我只想要大于0的值。

我已经乱搞了几个小时,我不确定是否必须更新构建字符串的逻辑,或者是否可以使用sql中的字符串函数来提取正确的值。

我目前拥有的例子:

{{1}}

我在拉动第一个值之后循环并连接字符串等。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

此单个查询将该字符串转换为包含[ItemNumber]和[ItemValue]列的表结果,以及仅返回值大于零的行。这对你有用吗?

DECLARE @OrderString VARCHAR(MAX) = '1=1;|2=|3=|4=1;|5=|';

WITH Step0 AS
(
    SELECT
        String = REPLACE(@OrderString, ';', '')
),
Step1 AS
(
    SELECT
        Block = SUBSTRING(String, 1, CHARINDEX('|', String) - 1),
        String = SUBSTRING(String, CHARINDEX('|', String) + 1, LEN(String))
    FROM
        Step0

    UNION ALL

    SELECT
        Block = SUBSTRING(String, 1, CHARINDEX('|', String) - 1),
        String = SUBSTRING(String, CHARINDEX('|', String) + 1, LEN(String))
    FROM
        Step1
    WHERE
        LEN(String) > 0
),

Step2 AS
(
    SELECT
        ItemNumber = SUBSTRING(Block, 1, CHARINDEX('=', Block) - 1),
        ItemValue = SUBSTRING(Block, CHARINDEX('=', Block) + 1, LEN(Block))
    FROM
        Step1
),

Step3 AS
(
    SELECT
        ItemNumber = CAST(ItemNumber AS INT),
        ItemValue = CAST(ItemValue AS INT)
    FROM
        Step2
    WHERE
        CAST(ItemValue AS INT) > 0
)

SELECT
    *
FROM
    Step3;
PS:发现这个运动好奇所以以为我会用它来发帖子,希望你不介意:

https://tangodude.wordpress.com/2014/02/16/t-sql-extracting-serialized-data-from-string-in-one-go/

答案 1 :(得分:0)

如果它是“从XML传入”,那么传入XML而不是字符串可能会好得多。将XML处理成您想要的内容非常简单。

你甚至可以做一些丑陋的事情让字符串回到XML:

DECLARE @OrderString VARCHAR(MAX) = '1=1;|2=|3=|4=1;|5=|';

DECLARE @xml XML
SELECT @xml = CAST('<order_line><item_id>'
             +REPLACE(REPLACE(REPLACE(STUFF(@OrderString,LEN(@OrderString),1,''),';',''),'|' ,'</quantity></order_line><order_line><item_id>'),'=','</item_id><quantity>')
             +'</quantity></order_line>' AS XML)

然后它非常简单:

SELECT c.value('(item_id)[1]', 'int') item_id
      ,c.value('(quantity)[1]', 'int') quantity
  FROM @xml.nodes('/order_line') T(c)