ДЛЯ ПУТИ XML и конкатенации строк - PullRequest
6 голосов
/ 20 июля 2011

Я пытаюсь создать значение, которое объединяет жестко закодированные строки и строки, созданные с использованием FOR XML PATH.

SUBSTRING(
(SELECT (', ' + [value]) 
 FROM [values]
 FOR XML PATH( '' )
), 3, 1000) +
' text in between my values ' +
SUBSTRING(
(SELECT (', ' + [otherValue]) 
 FROM [otherValues]
 FOR XML PATH( '' )
), 3, 1000)

Так что я ожидаю что-то вроде: Value1, Value2, Value3 text in between my values OtherValue1, OtherValue2, OtherValue3, но вместо этого я получаю пустую строку.

Если я извлекаю подстроки (включая запрос внутри нее), я получаю значения между штрафами, а если я добавляю только один из блоков подстрок, я получаю строку списка обратно. Поэтому я не могу понять, почему конкатенация с подстрокой и запросами FOR XML PATH приводит к тому, что она возвращает пустую строку .... HELP!

Ответы [ 3 ]

4 голосов
/ 27 июля 2011

Я думаю, что ваша первоначальная попытка почти у цели. Я делаю подобные вещи постоянно, используя один и тот же подход FOR XML. Приведенное ниже решение решает ваш точный пример и может быть легко адаптировано для других целей:

DECLARE @delimiter NVARCHAR(10)
SET @delimiter = ', '

declare @values TABLE (
    [value] NVARCHAR(25)
)

declare @otherValues TABLE (
    [otherValue] NVARCHAR(25)
)

INSERT INTO @values VALUES ('Value1')
INSERT INTO @values VALUES ('Value2')
INSERT INTO @values VALUES ('Value3')

INSERT INTO @otherValues VALUES ('OtherValue1')
INSERT INTO @otherValues VALUES ('OtherValue2')
INSERT INTO @otherValues VALUES ('OtherValue3')

SELECT
    STUFF(
        (
            SELECT
                @delimiter + CAST([value] AS NVARCHAR(500)) + '' AS [text()]
            FROM
                @values
            FOR   
                XML PATH('')
        ),
        1,
        LEN(REVERSE(@delimiter)), -- Reverse the delimiter string in case it has trailing spaces; LEN() won't count those
        ''
    ) +
    ' text in between my values ' +
    STUFF(
        (
            SELECT
                @delimiter + CAST([otherValue] AS NVARCHAR(500)) + '' AS [text()]
            FROM
                @otherValues
            FOR   
                XML PATH('')
        ),
        1,
        LEN(REVERSE(@delimiter)), -- Reverse the delimiter string in case it has trailing spaces; LEN() won't count those
        ''
    )
3 голосов
/ 20 июля 2011

Вам не нужно использовать функциональность XML для создания списка вещей, которые вы хотите. Он действительно не был создан для этого: он был создан для генерации XML. :)

Попробуй это. Я часто использую эту технику:

DECLARE @myList nvarchar(MAX)

SELECT
    @myList = COALESCE(@myList + ', ', '') + MyColumn
    FROM MyTable;

Для будущих читателей, пожалуйста, обратите внимание, что использование ORDER BY с этой техникой не гарантирует, что значения будут упорядочены в выходных данных; см здесь .

1 голос
/ 27 ноября 2013

Я думаю, вы получили пустую строку, потому что SUBSTRING Я не уверен, почему вы используете SUBSTRING чтобы получить результат, такой как «Value1, Value2, Value3 текст между моими значениями OtherValue1, OtherValue2, OtherValue3» попробуйте это.

SELECT
-- ISNULL( here in case [values] is empty table
    ISNULL(STUFF((
        SELECT ', ' + [value]
-- should be ', ' + NULLIF(value,'') or ', ' + ISNULL(value,'') depends on what you need
-- there is no column name for ', ' + [value], so AS [text()] is not need here
        FROM [values]
        FOR XML PATH(''),TYPE
    ).value('text()[1]','nvarchar(max)'), 1, 2, ''), '') +
-- you can replace PATH(''),TYPE).value('text()[1]','nvarchar(max)')
-- with PATH('')) it will be faster but if the values contain & > < etc. chars,
-- they will result in &amp &gt; &lt;  
    ' text in between my values ' +
    ISNULL(STUFF((
        SELECT ', ' + [otherValue] 
        FROM [otherValues] WHERE [otherValues]<>''
        FOR XML PATH(''),TYPE
    ).value('text()[1]','nvarchar(max)'), 1, 2, ''), '')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...