创建XML的“特定”形式,在SQL Server T-SQL中不使用字符串连接

问题描述 投票:0回答:1

我有一些奇怪的要求,它们要求特定的XML格式。由于截止日期短和缺乏技能,我决定做一个快速的解决方案,通过字符串连接生成XML。

DECLARE @tbl TABLE(personID int identity, name varchar(20), lastname varchar(20), country varchar(20));
INSERT INTO @tbl VALUES
 ('bob','bobby','USA')
,('mike','mikeson','Canada')
,('jack', 'jackson', 'Mexico')

select '<personID="' + cast(personID  as varchar) +'" country="' + country + '"/>' +
        '"<FIELD fieldname="name" value="' + name + '"/>' +
        '<FIELD fieldname="lastname" value="' + lastname + '"/>' +
'</personID>'
from @tbl

这给出了我需要的输出。但是,我已经无数次被告知这不是最佳实践,因此不鼓励通过字符串连接创建XML。还有其他一些方法可以使用更高级的XML技术来实现相同的结果吗?

sql sql-server xml tsql concatenation
1个回答
2
投票
--string concat, is it valid xml??
select try_cast('<personID="' + cast(personID  as varchar) +'" country="' + country + '"/>' +
        '"<FIELD fieldname="name" value="' + name + '"/>' +
        '<FIELD fieldname="lastname" value="' + lastname + '"/>' +
'</personID>' as xml)
from @tbl;

--..add null columns
INSERT INTO @tbl VALUES
,(null, null, null)
,(null, 'null name', null)
,('null lastname', null, null);

--exclude fieldname for null columns
select
(
select t.personID as '@ID', t.country as '@country',
    case when t.name is not null then 'name' end as 'FIELD/@fieldname', 
    t.name as 'FIELD/@value',
    '',
    case when t.lastname is not null then 'lastname' end as 'FIELD/@fieldname', t.lastname as 'FIELD/@value'
for xml path('person'), type
)   
from @tbl t
where name is not null or lastname is not null or country is not null;

--A
select
(
select t.personID as '@ID', t.country as '@country',
    'name' as 'FIELD/@fieldname', t.name as 'FIELD/@value',
    '',
    'lastname' as 'FIELD/@fieldname', t.lastname as 'FIELD/@value'
for xml path('person'), type
)   
from @tbl t;

--B
select
(
select t.personID as 'person/@ID', t.country as 'person/@country',
    'name' as 'person/FIELD/@fieldname', t.name as 'person/FIELD/@value',
    '' as 'person',
    'lastname' as 'person/FIELD/@fieldname', t.lastname as 'person/FIELD/@value'
for xml path(''), type
)   
from @tbl t;


--single xml for the whole table
select t.personID as '@ID', t.country as '@country',
    'name' as 'FIELD/@fieldname', t.name as 'FIELD/@value',
    '',
    'lastname' as 'FIELD/@fieldname', t.lastname as 'FIELD/@value'
from @tbl t
for xml path('person');
© www.soinside.com 2019 - 2024. All rights reserved.