对于 xml 缺少空列

Jee*_*ena 4 xml sql-server

当我们使用 for xml 子句从一行创建 xml 时,如下所示

select * from Menus where MenuID=100 for xml path('')
Run Code Online (Sandbox Code Playgroud)

xml 将错过具有 NULL 作为值的列。

我有一个像

select * from Menus where MenuID=100  for xml path('') , ELEMENTS XSINIL
Run Code Online (Sandbox Code Playgroud)

但是 xml 只会创建如下

<MenuID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">100</MenuID>
<MenuOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1</MenuOrder>
Run Code Online (Sandbox Code Playgroud)

有没有办法用NULL列创建如下

<MenuID>100</MenuID>
<MenuOrder>1</MenuOrder>
Run Code Online (Sandbox Code Playgroud)

Mik*_*son 5

如果不想使用xsi:nil,则必须决定当表中的值为null. 对于字符串,它可能适合使用空字符串。对于整数,您可能希望先使用0-1将列数据转换为字符串,然后对整数也使用空字符串。你必须决定你想要什么值并使用isnullcast来获得你想要的输出。

例子:

declare @T table
(
  MenuID int,
  MenuOrder int,
  MenuName varchar(10)
)

insert into @T default values

select -- 0 instead of null
       isnull(MenuID, 0) as MenuID, 
       -- empty string instead of null
       isnull(cast(MenuOrder as varchar(11)), '') as MenuOrder,  
       -- The text value NULL instead of null
       isnull(MenuName, 'NULL') as MenuName  
from @T as T
for xml path('')
Run Code Online (Sandbox Code Playgroud)

结果:

<MenuID>0</MenuID>
<MenuOrder></MenuOrder>
<MenuName>NULL</MenuName>
Run Code Online (Sandbox Code Playgroud)

如果您想在将表名作为参数的情况下动态执行此操作,并且您决定无论数据类型如何,都可以使用空字符串,您可以执行以下操作。

-- Table parameter
declare @TableName varchar(128) = 'Menus';
-- Column to use in where clause
declare @ColumnName varchar(128) = 'MenuID';
-- Value to filter by
declare @ColumnValue int = 100;

declare @S nvarchar(max);

set @S = '
select '+
  stuff((
        select ', isnull(cast('+quotename(C.name)+' as nvarchar(max)), '''') as '+quotename(C.name)
        from sys.columns as C 
        where C.object_id = object_id(@TableName)
        for xml path('')
        ), 1, 2, '')+'
from '+quotename(@TableName)+'
where '+quotename(@ColumnName)+' = @ColumnValue
for xml path('''')';

exec sp_executesql @S, N'@ColumnValue int', @ColumnValue;
Run Code Online (Sandbox Code Playgroud)

如果表名是参数,您显然还需要参数化要使用的列和值。

动态生成的查询:

select isnull(cast([MenuID] as nvarchar(max)), '') as [MenuID], isnull(cast([MenuOrder] as nvarchar(max)), '') as [MenuOrder]
from [Menus]
where [MenuID] = @ColumnValue
for xml path('')
Run Code Online (Sandbox Code Playgroud)