有没有办法可以将SQL Server 2008表格转换为HTML表格文本,而不首先知道表格的结构?
我试过了:
USE [Altiris]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spCustomTable2HTML] (
@TABLENAME NVARCHAR(500),
@OUTPUT NVARCHAR(MAX) OUTPUT,
@TBL_STYLE NVARCHAR(1024) = '',
@HDR_STYLE NVARCHAR(1024) = '')
AS
-- @exec_str stores the dynamic SQL Query
-- @ParmDefinition stores the parameter definition for the dynamic SQL
DECLARE @exec_str NVARCHAR(MAX)
DECLARE @ParmDefinition NVARCHAR(500)
--We need to use Dynamic SQL at this point so we can expand the input table name parameter
SET @exec_str= N'
DECLARE @exec_str NVARCHAR(MAX)
DECLARE @ParmDefinition NVARCHAR(500)
--Make a copy of the original table adding an indexing columnWe need to add an index column to the table to facilitate sorting so we can maintain the
--original table order as we iterate through adding HTML tags to the table fields.
--New column called CustColHTML_ID (unlikely to be used by someone else!)
--
select CustColHTML_ID=0,* INTO #CustomTable2HTML FROM ' + @TABLENAME + '
--Now alter the table to add the auto-incrementing index. This will facilitate row finding
DECLARE @COUNTER INT
SET @COUNTER=0
UPDATE #CustomTable2HTML SET @COUNTER = CustColHTML_ID=@COUNTER+1
-- @HTMLROWS will store all the rows in HTML format
-- @ROW will store each HTML row as fields on each row are iterated through
-- using dymamic SQL and a cursor
-- @FIELDS will store the header row for the HTML Table
DECLARE @HTMLROWS NVARCHAR(MAX) DECLARE @FIELDS NVARCHAR(MAX)
SET @HTMLROWS='''' DECLARE @ROW NVARCHAR(MAX)
-- Create the first HTML row for the table (the table header). Ignore our indexing column!
SET @FIELDS=''<tr ' + @HDR_STYLE + '>''
SELECT @FIELDS=COALESCE(@FIELDS, '' '','''')+''<td>'' + name + ''</td>''
FROM tempdb.sys.Columns
WHERE object_id=object_id(''tempdb..#CustomTable2HTML'')
AND name not like ''CustColHTML_ID''
SET @FIELDS=@FIELDS + ''</tr>''
-- @ColumnName stores the column name as found by the table cursor
-- @maxrows is a count of the rows in the table, and @rownum is for marking the
-- ''current'' row whilst processing
DECLARE @ColumnName NVARCHAR(500)
DECLARE @maxrows INT
DECLARE @rownum INT
--Find row count of our temporary table
SELECT @maxrows=count(*) FROM #CustomTable2HTML
--Create a cursor which will look through all the column names specified in the temporary table
--but exclude the index column we added (CustColHTML_ID)
DECLARE col CURSOR FOR
SELECT name FROM tempdb.sys.Columns
WHERE object_id=object_id(''tempdb..#CustomTable2HTML'')
AND name not like ''CustColHTML_ID''
ORDER BY column_id ASC
--For each row, generate dymanic SQL which requests the each column name in turn by
--iterating through a cursor
SET @rowNum=0
SET @ParmDefinition=N''@ROWOUT NVARCHAR(MAX) OUTPUT,@rowNum_IN INT''
While @rowNum < @maxrows
BEGIN
SET @HTMLROWS=@HTMLROWS + ''<tr>''
SET @rowNum=@rowNum +1
OPEN col
FETCH NEXT FROM col INTO @ColumnName
WHILE @@FETCH_STATUS=0
BEGIN
--Get nth row from table
--SET @exec_str=''SELECT @ROWOUT=(select top 1 ['' + @ColumnName + ''] from (select top '' + cast(@rownum as varchar) + '' * from #CustomTable2HTML order by CustColHTML_ID ASC) xxx order by CustColHTML_ID DESC)''
SET @exec_str=''SELECT @ROWOUT=(select ['' + @ColumnName + ''] from #CustomTable2HTML where CustColHTML_ID=@rowNum_IN)''
EXEC sp_executesql
@exec_str,
@ParmDefinition,
@ROWOUT=@ROW OUTPUT,
@rowNum_IN=@rownum
SET @HTMLROWS =@HTMLROWS + ''<td>'' + @ROW + ''</td>''
FETCH NEXT FROM col INTO @ColumnName
END
CLOSE col
SET @HTMLROWS=@HTMLROWS + ''</tr>''
END
SET @OUTPUT=''''
IF @maxrows>0
SET @OUTPUT= ''<table ' + @TBL_STYLE + '>'' + @FIELDS + @HTMLROWS + ''</table>''
DEALLOCATE col
'
DECLARE @ParamDefinition nvarchar(max)
SET @ParamDefinition=N'@OUTPUT NVARCHAR(MAX) OUTPUT'
--Execute Dynamic SQL. HTML table is stored in @OUTPUT which is passed back up (as it's
--a parameter to this SP)
EXEC sp_executesql @exec_str,
@ParamDefinition,
@OUTPUT=@OUTPUT OUTPUT
RETURN 1
但是当我执行程序时
DECLARE @HTML NVARCHAR(MAX)
EXEC SpCustomTable2HTML 'Users', @HTML OUTPUT
SELECT @HTML
它不断返回null
。
有什么想法吗?
答案 0 :(得分:2)
此SQL Fiddle DEMO显示您的问题。当所有行中的所有列都具有值时,您将获得正确的HTML表。当ANY NULL 存在时,它将整个事物变为NULL,因为
NULL +
<any>
= NULL
要修复它,只需更改第90行以处理空值,即
SET @HTMLROWS = @ HTMLROWS +&#39;&#39;&#39;&#39;&#39; + ISNULL(@ROW,&#39;&#39;&#39;&#39;) +&#39;&#39;&#39;&#39;
答案 1 :(得分:0)
我意识到这已经有一段时间了(至少可以说),因为这个问题很活跃,但我想我会在这个帖子上发表一些评论,因为它在最近的一次搜索中出现了。
道歉,如果这(无意)惹恼了提问者,但我相信使用的方法既低效又难以理解 - 因此维持。
在使用数据库数据生成HTML表之前,无需复制数据库数据。这只是我的拙见,但使用动态SQL生成动态SQL也是违反直觉的。
此外,需要转义包含HTML标记(或更糟糕的是,格式错误的 HTML标记)的数据库数据值,以便可以正确呈现它们。例如,诸如“值> 10”的数据库数据需要生成HTML“&lt; td&gt;值&amp; gt; 10&lt; / td&gt;”。
以下代码通过使用内置的FOR XML子句解决了上述所有问题:
CREATE PROCEDURE dbo.spCustomTable2HTML
@TABLENAME nvarchar(500),
@TBL_STYLE nvarchar(1024) = '',
@HDR_STYLE nvarchar(1024) = '',
@OUTPUT nvarchar(MAX) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
-- Declare variables
DECLARE @Columns nvarchar(MAX) = '',
@Data nvarchar(MAX),
@SQL nvarchar(MAX);
-- Snapshot columns (to force use of tempdb)
IF OBJECT_ID('tempdb.dbo.##spCustomTable2HTMLColumns') IS NOT NULL
BEGIN
DROP TABLE ##spCustomTable2HTMLColumns;
END
SET @SQL =
'SELECT TOP 0 *
INTO ##spCustomTable2HTMLColumns
FROM ' + @TABLENAME;
EXEC sp_executesql @SQL;
-- Build header row
SET @OUTPUT = (SELECT name AS td
FROM tempdb.sys.columns
WHERE object_id = OBJECT_ID('tempdb.dbo.##spCustomTable2HTMLColumns')
ORDER BY column_id
FOR XML RAW(''), ELEMENTS);
SET @OUTPUT += '</tr>'
-- Build column list
SELECT @Columns += '[' + name + '] AS td,'
FROM tempdb.sys.columns
WHERE object_id = OBJECT_ID('tempdb.dbo.##spCustomTable2HTMLColumns')
ORDER BY column_id;
SET @Columns = LEFT(@Columns, LEN(@Columns) - 1); -- Strip trailing comma
-- Delete columns snapshot
DROP TABLE ##spCustomTable2HTMLColumns;
-- Build data rows
SET @SQL =
'SET @Data = CONVERT(varchar(MAX),
(SELECT ' + @Columns +
' FROM ' + @TABLENAME +
' FOR XML RAW (''tr''), ELEMENTS XSINIL))';
EXEC sp_executesql @SQL, N'@Data NVARCHAR(MAX) OUTPUT', @Data = @Data OUTPUT;
SET @Data = REPLACE(@Data, ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', ''); -- Remove XSI namespace
SET @Data = REPLACE(@Data, ' xsi:nil="true"', ''); -- Remove XSI attributes
SET @OUTPUT += @Data;
-- Prefix table/row headers
SET @OUTPUT = REPLACE(@OUTPUT, ' ', ' '); -- Use non-breaking spaces
SET @OUTPUT = REPLACE(@OUTPUT, '</tr>', '</tr>' + CHAR(13) + CHAR(10)); -- Add new line per row (to improve rendering in Microsoft Outlook)
SET @OUTPUT = '<table ' + @TBL_STYLE + '>' +
'<tr ' + @HDR_STYLE + '>' +
@OUTPUT +
'</table>';
END