如何在SQL Server 2008中拆分String

时间:2015-01-14 12:03:51

标签: sql-server sql-server-2008

我想使用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的价值。

请建议我以任何方式执行此操作。

提前致谢

6 个答案:

答案 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)

将半列分隔值拆分为新行更安全。

enter image description here

<强> 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()函数。