我有以下的T-SQL数据库的电子邮件。
-- create proc TableToHtml @table varchar(max) as
declare @table varchar(max) = '(select 1 a, ''one'' b union all select 2, ''two'') t '
declare @sql varchar(max) = '
declare @xml xml = (
select * from ' + @table + '
for xml path(''tr''), root(''table'')
);
select @xml'
declare @tmp table (x xml)
insert into @tmp exec(@sql)
declare @x xml = (select x from @tmp)
select @x
并返回
<table>
<tr>
<a>1</a>
<b>one</b>
</tr>
<tr>
<a>2</a>
<b>two</b>
</tr>
</table>
是否有可能写的XQuery让它返回下面的HTML?
<table>
<tr>
<th>a</th>
<th>b</th>
</tr>
<tr>
<td>1</td>
<td>one</td>
</tr>
<tr>
<td>2</td>
<td>two</td>
</tr>
</table>
我想出了一个少一个黑客。 唯一的问题是它会造成<td />
代替<td></td>
如果该值是空值。 这会造成一些问题,布局当电子邮件被发送到一些旧的Outlook客户端。
declare @table varchar(max) = '(select 1 a, ''one'' b union all select 2, ''two'') t '
declare @sql varchar(max) = '
declare @xml xml = (
select * from ' + @table + '
for xml path(''tr''), root(''table'')
);
select @xml'
declare @tmp table (x xml)
insert into @tmp exec(@sql)
declare @x xml = (select x from @tmp)
select @x.query('<body>
<table>
<tr>
{for $c in /table/tr[1]/* return element th { local-name($c) } }
</tr>
{
for $r in /table/*
return element tr { for $c in $r/* return element td { data($c) } }
}
</table>
</body>')
主要劈警惕!
有可能是一个更优雅的方式来做到这一点,但这里是快速破解:
declare @xml xml = (
select * from (
select 'a' + '</th><th>' + 'b' as th, null as td
union all
select null, '1' + '</td><td>' + 'one'
union all
select null, '2' + '</td><td>' + 'two'
) t
for xml path('tr'), root('table')
);
select cast(replace(replace(cast(@xml as varchar(max)), '</th><th>', '</th><th>'), '</td><td>', '</td><td>') as xml)
输出:
<table>
<tr>
<th>a</th>
<th>b</th>
</tr>
<tr>
<td>1</td>
<td>one</td>
</tr>
<tr>
<td>2</td>
<td>two</td>
</tr>
</table>
哈克列表:
- 使用零点得到th和td在同一个“栏”
- 明确添加你的头值A和B.
- 串联列值,并明确提出结束和中间开始标记
- XML转换为varchar
- 替换尖括号版本这些标签的消毒版本
- 转换回XML
这在很大程度上大概可以重构使用变量,或许可以从你的输入/数据收集。
注意:
一般来说,你应该让你的演示文稿层为您创建的HTML。 你也许可以让一个泛型函数在你的数据库从表中创建HTML,但已经有这么多伟大的演示类,控制等,旨在做正是这一点。 您的应用程序几乎总是能规模比你的数据库更好。