我想使用T-SQL查询拆分字符串,而不创建任何函数或存储过程。
例如,我有一个像
这样的字符串"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"
现在我想获得Job Type
New
的价值。
请建议我以任何方式执行此操作。
提前致谢
答案 0 :(得分:0)
这应该有效,但它取决于属性的顺序:
select substring(@string, charindex('Job Type', @string) + 17, charindex('Proof Number', @string) - 82)
<德尔>
我用“作业类型”的其他值测试了它,它看起来效果很好。如果属性的顺序发生变化,此过程将不再有效......
德尔>
抓一切 - 如果第一个属性的值发生变化,将不再有效......以下应该处理任何大小的值:
declare @string varchar(max) = '"Attribute "Request Type" value: asdfasdf; Attribute "Job Type" value: ReallyLongString; Attribute "Proof Number" value: BiggerValue; Attribute "Vision Number" value: 534290;"'
declare @stringToUse varchar(max) = substring(@string, charindex('Job Type', @string), charindex('Proof Number', @string))
select @stringToUse
select charindex('Job Type', @stringToUse)
select charindex('Proof Number', @stringToUse)
select substring(@stringToUse, charindex('Job Type', @stringToUse) + 17, charindex('Proof Number', @stringToUse) - 31)
答案 1 :(得分:0)
你可以这样做:
GO
DECLARE @str VARCHAR(MAX);
SET @str = '"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"';
SELECT SUBSTRING(SUBSTRING(@str, CHARINDEX('JOB TYPE', @str) + 17, LEN(@str) - CHARINDEX('JOB TYPE', @str) + 17), 1, CHARINDEX('Attribute', @str) + 1);
(OR)
SELECT SUBSTRING(SUBSTRING('"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"',CHARINDEX ('JOB TYPE','"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"')+17,LEN('"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"')-CHARINDEX ('JOB TYPE','"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"')+17),1,CHARINDEX ('Attribute','"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"')+1);
答案 2 :(得分:0)
如果您真的想在一个查询中执行此操作,那么您可以使用以下CTE方法,但它是严格硬编码的,您可以改进它以供动态使用:
DECLARE @List NVARCHAR(MAX) = N'Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;'
DECLARE @Delimiter NVARCHAR(255) = N';'
DECLARE @ll INT = LEN(@List) + 1, @ld INT = LEN(@Delimiter);
WITH a AS
(
SELECT
[start] = 1,
[end] = COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, 1), 0), @ll),
[value] = LTRIM(RTRIM(REPLACE(
SUBSTRING(@List, 1,
COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, 1), 0), @ll) - 1)
, 'Attribute', '')))
UNION ALL
SELECT
[start] = CONVERT(INT, [end]) + @ld,
[end] = COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, [end] + @ld), 0), @ll),
[value] = LTRIM(RTRIM(REPLACE(
SUBSTRING(@List, [end] + @ld,
COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, [end] + @ld), 0), @ll)-[end]-@ld)
, 'Attribute', '')))
FROM a
WHERE [end] < @ll
)
SELECT LTRIM(RTRIM(REPLACE(REPLACE(
REPLACE([value],'"Job Type"', '')
, 'value', ''),':','')
))
FROM a
WHERE LEN([value]) > 0 AND [value] LIKE '%Job Type%'
OPTION (MAXRECURSION 0);
但我必须鼓励您使用UDF将字符串转换为表格然后使用它。 最初的想法来自Common Table Expression
答案 3 :(得分:0)
这也适用于其他属性,只需更改where语句。
将您的数据修改为XML:
DECLARE @txt varchar(max) =
'"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"'
SELECT
RIGHT(t.c.value('.', 'VARCHAR(2000)'),
PATINDEX('%_ :eulav%', REVERSE(t.c.value('.', 'VARCHAR(2000)'))))
FROM (
SELECT x = CAST('<t>' +
REPLACE(STUFF(REVERSE(STUFF(REVERSE(@txt), 1,2, '')), 1, 1, '; '),
'; Attribute ', '</t><t>') + '</t>' AS XML)
) a
CROSS APPLY x.nodes('/t') t(c)
WHERE t.c.value('.', 'VARCHAR(2000)') like '"Job Type"%'
结果:
New
答案 4 :(得分:0)
将半列分隔值拆分为新行更安全。
<强> QUERY 强>
DECLARE @STR NVARCHAR(MAX)='"Attribute "Request Type" value: Prior; Attribute "Job Type" value: New; Attribute "Proof Number" value: 1; Attribute "Vision Number" value: 534290;"'
-- You can pass your desired Attribute to get the value
DECLARE @ATTRIBUTENAME VARCHAR(100)='Job Type'
-- Extracts the value after the semi column
SELECT Ids,RIGHT(Ids,LEN(Ids)-CHARINDEX(':',Ids)) VALUE
FROM
( -- Converts the Semi column seperated values to rows
SELECT PARSENAME(REPLACE(Split.a.value('.', 'NVARCHAR(MAX)'),'"',''),1) 'Ids'
FROM
(
-- Select the string in XML format
SELECT CAST ('<M>' + REPLACE(@STR, ';', '</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)TAB
WHERE Ids LIKE '%Attribute%' AND Ids LIKE '%'+@ATTRIBUTENAME+'%'
答案 5 :(得分:0)
这是我的简单解决方案:
CREATE FUNCTION [dbo].[fnMakeTableFromList](
@List VARCHAR(MAX),
@Delimiter VARCHAR(255))
RETURNS TABLE
AS
RETURN (SELECT
Item =
CONVERT(
VARCHAR,
Item)
FROM
(SELECT
Item =
x.i.value(
'(./text())[1]',
'varchar(max)')
FROM
(SELECT
[XML] =
CONVERT(
XML,
'<i>' +
REPLACE(
@List,
@Delimiter,
'</i><i>') +
'</i>').query('.')) AS a
CROSS APPLY [XML].nodes('i') AS x(i)) AS y
WHERE
Item IS NOT NULL);
GO
该函数从字面上接受一个以空格或其他字符分隔的字符串,并将其转换为功能表对象,您可以在自己的查询中使用该对象。由于SQL没有这样的“数组”对象,因此表是 array 。
在较新的SQL中,您仅需要STRING_SPLIT()函数。