SQL查询使用子字符串来分隔数据

时间:2016-08-10 08:23:17

标签: sql sql-server

我有这样的数据,我需要根据它分开它们 account = 10825,实例id = 0

我已经尝试使用带有charindex的子字符串,但需要改进以进一步查询,因为它每次都不是相同的格式。

数据: 1:

Month=12&Year=2015&Accounts=[10825].[44].[1]&Users=[RL665480003].[44]&Culture=en-US&DMSWebService=http%3A%2F%2Fausydapi01.recall.com%2Fdmswebservice%2Fdmswebservice.svc&OLTAccountID=0&OLTInstanceID=0&DaystoDestroy=90&LastLoadDate=12%2F30%2F2015 00%3A00%3A00&connectionString=Data Source%3Damatldb09%3BInitial Catalog%3DLocalizationDB%3BUser ID%3Dlocalization%3BPassword%3Dr3call%3B&ResourceType=BICustomerPortal&LastLoadDateDW=12%2F31%2F2015 12%3A00%3A00 AM&Period=12%2F30%2F2015 00%3A00%3A00

2:

Culture=en-US&Month=12&Year=2015&Accounts=[2784].[6].[1]&Users=[RL042671018].[6]&DMSWebService=http%3A%2F%2Fruss-app.recall.com%2Fdmswebservice%2Fdmswebservice.svc&OLTAccountID=0&OLTInstanceID=0&DaystoDestroy=90&ResourceType=BICustomerPortal&connectionString=Data Source%3Damatldb09%3BInitial Catalog%3DLocalizationDB%3BUser ID%3Dlocalization%3BPassword%3Dr3call%3B

2 个答案:

答案 0 :(得分:0)

你所拥有的内容看起来像来自浏览器的查询字符串(或一组发布的变量)。所以它的长度会有所不同,也许变量的顺序和数量也可能发生变化。

因此,我能想到的唯一可靠的方法是有效地反序列化查询字符串。由于您使用的是SQL,我们将把它放到临时表中。您可以使用查询字符串中使用的特殊字符:“&” (以分隔参数)和“=”(将参数名称与值分开)作为标记来执行此操作。

DECLARE @data nvarchar(MAX)
-- using your first data sample as an example:
SET @data = 'Month=12&Year=2015&Accounts=[10825].[44].[1]&Users=[RL665480003].[44]&Culture=en-US&DMSWebService=http%3A%2F%2Fausydapi01.recall.com%2Fdmswebservice%2Fdmswebservice.svc&OLTAccountID=0&OLTInstanceID=0&DaystoDestroy=90&LastLoadDate=12%2F30%2F2015 00%3A00%3A00&connectionString=Data Source%3Damatldb09%3BInitial Catalog%3DLocalizationDB%3BUser ID%3Dlocalization%3BPassword%3Dr3call%3B&ResourceType=BICustomerPortal&LastLoadDateDW=12%2F31%2F2015 12%3A00%3A00 AM&Period=12%2F30%2F2015 00%3A00%3A00'

DECLARE @workingtable TABLE
(
    ID [int] IDENTITY(1, 1),
    ItemID [nvarchar](2000),
    ItemValue [nvarchar](2000)
)

DECLARE @Item nvarchar(4000)
        ,@ItemID [nvarchar](2000)
        ,@ItemValue [nvarchar](2000)
        ,@pos int
        ,@count int
        ,@row int
        ,@delimiter1 varchar(1)
        ,@delimiter2 varchar(1);

SET @delimiter1 = '&';
SET @delimiter2 = '='
SET @data = LTRIM(RTRIM(@data)) + @delimiter1
SET @pos = CHARINDEX(@delimiter1, @data, 1)
SET @count = 0;
SET @row = 0;

IF REPLACE(@data, @delimiter1, '') <> '' -- make sure there are actually any delimited items in the list
BEGIN
    WHILE @pos > 0
    BEGIN
        SET @count = @count + 1
        SET @Item = LTRIM(RTRIM(LEFT(@data, @pos - 1))) -- get the querystring parameter and its value
        SET @ItemID = LTRIM(RTRIM(LEFT(@Item, CHARINDEX(@delimiter2, @Item) -1))) -- now extract the parameter value
        SET @ItemValue = LTRIM(RTRIM(RIGHT(@Item, LEN(@Item) - CHARINDEX(@delimiter2, @Item)))) -- now extract the parameter name
        INSERT INTO @workingtable ([ItemID], [ItemValue]) VALUES (@ItemID, @ItemValue) -- store in working table

        SET @data = RIGHT(@data, LEN(@data) - @pos) -- remove the item we just extracted from the list
        SET @pos = CHARINDEX(@delimiter1, @data, 1) -- reset the position to point to the next delimiter
    END
END

SELECT ItemID, ItemValue FROM @workingtable

一旦你有了,你就可以很容易地找到你想要的具体价值。您提到了“帐户”字段的第一部分。所以你可以像这样得到整个账户字段:

    SELECT ItemValue FROM @workingtable WHERE [ItemID] = 'Accounts'

或找到这样的具体部分:

    SELECT SUBSTRING(ItemValue, CHARINDEX('[', [ItemValue]) + 1, CHARINDEX(']', [ItemValue]) - 2) FROM @workingtable WHERE [ItemID] = 'Accounts'

显然,如果您希望此功能可以轻松重复使用,我建议您将其封装在一个函数或过程中。

希望有所帮助。

答案 1 :(得分:0)

或者你可以使用以下限制,即accountid的len不超过100个字符。

declare @str varchar(1000)
set @str='Month=12&Year=2015&Users=[RL665480003].[44]&Culture=en-US&DMSWebService=http%3A%2F%2Fausydapi01.recall.com%2Fdmswebservice%2Fdmswebservice.svc&OLTAccountID=0&OLTInstanceID=0&DaystoDestroy=90&LastLoadDate=12%2F30%2F2015 00%3A00%3A00&connectionString=Data Source%3Damatldb09%3BInitial Catalog%3DLocalizationDB%3BUser ID%3Dlocalization%3BPassword%3Dr3call%3B&ResourceType=BICustomerPortal&LastLoadDateDW=12%2F31%2F2015 12%3A00%3A00 AM&Period=12%2F30%2F2015 00%3A00%3A00&Accounts=[10825].[44].[1]'

select SUBSTRING(SUBSTRING(@str,  patindex('%Accounts=[[]%', @str) + len('Accounts=[') ,  100) , 0 ,  patindex('%]%', SUBSTRING(@str, patindex('%Accounts=[[]%', @str) + len('Accounts=[') ,  100)) )