我需要在包含查询字符串的列中执行select:
user_id=300&company_id=201503&status=WAITING OPERATION&count=1
我想在新列中执行select和break每个值,例如:
user_id | company_id | status | count
300 | 201503 | WAITING OPERATION | 1
如何在不使用procs的情况下在SQL Server中执行此操作?
我尝试了一个功能:
CREATE FUNCTION [xpto].[SplitGriswold]
(
@List NVARCHAR(MAX),
@Delim1 NCHAR(1),
@Delim2 NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT
Val1 = PARSENAME(Value,2),
Val2 = PARSENAME(Value,1)
FROM
(
SELECT REPLACE(Value, @Delim2, '&') FROM
(
SELECT LTRIM(RTRIM(SUBSTRING(@List, [Number],
CHARINDEX(@Delim1, @List + @Delim1, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(@List)
AND SUBSTRING(@Delim1 + @List, [Number], LEN(@Delim1)) = @Delim1
) AS y(Value)
) AS z(Value)
);
GO
执行:
select QueryString
from User.Log
CROSS APPLY notifier.SplitGriswold(REPLACE(QueryString, ' ', N'ŏ'), N'ŏ', '&') AS t;
但是它只返回一列全部内容:
QueryString
user_id=300&company_id=201503&status=WAITING OPERATION&count=1
提前致谢。
答案 0 :(得分:1)
我以前必须多次这样做,而且你很幸运!由于每个字符串只有3个分隔符,并且该数字是固定的,因此您可以使用SQL Server的PARSENAME
函数来执行此操作。这比最好的替代品(使用XML解析的东西)要小得多。试试这个(未经测试的)查询(用适当的名称替换TABLE_NAME和COLUMN_NAME):
SELECT
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),1) AS 'User',
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),2) AS 'Company_ID',
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),3) AS 'Status',
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),4) AS 'Count',
FROM TABLE_NAME
那将以#34; user_id = 300&#34;形式为您提供结果,这远远不是您想要的难点。我会留给你做容易的部分(在&#34; =&#34;签名之前放下东西)。
注意:我无法记住PARSENAME是否会对非法名称字符(&#34; =&#34;符号)感到不满。如果是这样,只需在其中嵌套另一个REPLACE,将其转换为其他内容,如下划线。
答案 1 :(得分:-1)
您需要使用SQL SUBSTRING作为select语句的一部分。您首先需要构建第一行,然后使用UNION返回第二行。