Sql 将存储过程的Html输出到表或变量中
我有一个存储过程dbo.someprocedure,它将输入作为sql查询并返回Html表格式Sql 将存储过程的Html输出到表或变量中,sql,sql-server,database,stored-procedures,azure-sql-database,Sql,Sql Server,Database,Stored Procedures,Azure Sql Database,我有一个存储过程dbo.someprocedure,它将输入作为sql查询并返回Html表格式 Exec someprocedure 'Select * from dbo.Table' 我希望将这个html插入到表或变量中,以便对结果html执行一些更改 我试着用 Declare @variable varchar(max) Exec @variable = someprocedure 'Select * from dbo.Table' 它正在执行,但返回0。未分配变量 提前感谢,期待您的
Exec someprocedure 'Select * from dbo.Table'
我希望将这个html插入到表或变量中,以便对结果html执行一些更改
我试着用
Declare @variable varchar(max)
Exec @variable = someprocedure 'Select * from dbo.Table'
它正在执行,但返回0。未分配变量
提前感谢,期待您的回答 @SeanLange说的是对的。若要使用SQL存储过程将SQL表转换为HTML,则在执行SQL存储过程时必须使用输出 例如-我的表格: 创建存储过程
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[CustomTable2HTMLv4]
(@TSQL_QUERY NVARCHAR(4000),
@OUTPUT NVARCHAR(MAX) OUTPUT,
@TBL_STYLE NVARCHAR(1024) = '',
@ALIGNMENT INT = 0)
AS
-- @exec_str stores the dynamic SQL Query
DECLARE @exec_str NVARCHAR(MAX)
-- @ParmDefinition stores the parameter definition for the dynamic SQL
DECLARE @ParmDefinition NVARCHAR(500)
IF @ALIGNMENT = 0
BEGIN
-- 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)
DECLARE @DEBUG INT
SET @DEBUG = 0
IF @DEBUG=1 Print ''Table2HTML -Horizontal alignment''
-- Make a copy of the original table adding an indexing column. We 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 columns.
-- New column called CustColHTML_ID (unlikely to be used by someone else!)
--
select CustColHTML_ID=0,* INTO #CustomTable2HTML FROM (' + @TSQL_QUERY + ') SUB
IF @DEBUG=1 PRINT ''Created temporary custom table''
--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
IF @DEBUG=1 PRINT ''Added counter column to custom table''
-- @HTMLROWS will store all the rows in HTML format
-- @ROW will store each HTML row as fields on each row are iterated through
-- using dynamic 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!
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>''
IF @DEBUG=1 PRINT ''table fields: '' + @FIELDS
-- @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 dynamic SQL which requests the each column name in turn by
--iterating through a cursor
SET @rowNum=1
SET @ParmDefinition=N''@ROWOUT NVARCHAR(MAX) OUTPUT,@rowNum_IN INT''
While @rowNum <= @maxrows
BEGIN
SET @HTMLROWS=@HTMLROWS + ''<tr>''
OPEN col
FETCH NEXT FROM col INTO @ColumnName
IF @DEBUG=1 Print ''@ColumnName: '' + @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)''
IF @DEBUG=1 PRINT ''@exec_str: '' + @exec_str
EXEC sp_executesql
@exec_str,
@ParmDefinition,
@ROWOUT=@ROW OUTPUT,
@rowNum_IN=@rownum
IF @DEBUG=1 SELECT @ROW as ''@Row''
SET @HTMLROWS =@HTMLROWS + ''<td>'' + IsNull(@ROW,'''') + ''</td>''
FETCH NEXT FROM col INTO @ColumnName
END
CLOSE col
SET @rowNum=@rowNum +1
SET @HTMLROWS=@HTMLROWS + ''</tr>''
END
SET @OUTPUT=''''
IF @maxrows>0
SET @OUTPUT= ''<table ' + @TBL_STYLE + '>'' + @FIELDS + @HTMLROWS + ''</table>''
DEALLOCATE col
'
END
ELSE
BEGIN
--This is the SQL String for table columns to be aligned on
--the vertical. So we select a table column, and then iterate
--through all the rows for that column, this forming one row
--of our html table.
SET @exec_str= N'
DECLARE @exec_str NVARCHAR(MAX)
DECLARE @ParmDefinition NVARCHAR(500)
DECLARE @DEBUG INT
SET @DEBUG=0
IF @DEBUG=1 Print ''Table2HTML -Vertical alignment''
--Make a copy of the original table adding an indexing column.
--We 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 (' + @TSQL_QUERY + ') SUB
IF @DEBUG=1 PRINT ''CustomTable2HTMLv2: Modfied temporary table''
--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 dynamic SQL and a cursor
DECLARE @HTMLROWS NVARCHAR(MAX)
DECLARE @ROW NVARCHAR(MAX)
SET @HTMLROWS=''''
-- @ColumnName stores the column name as found by the table cursor
-- @maxrows is a count of the rows in the table
DECLARE @ColumnName NVARCHAR(500)
DECLARE @maxrows INT
--Find row count of our temporary table
--This is used here purely to see if we have any data to output
SELECT @maxrows=count(*) FROM #CustomTable2HTML
--Create a cursor which will iterate through all the column names
--in the temporary table (excepting the one we added above)
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 **HTML** row, we need to for each iterate through
--each table column as the outer loop.
--Once the column name is identified, we use Coalesc to
--combine all the column values into a single string.
SET @ParmDefinition=N''@COLOUT NVARCHAR(MAX) OUTPUT''
OPEN col
FETCH NEXT FROM col INTO @ColumnName
WHILE @@FETCH_STATUS=0
BEGIN
--Using current column name, grab all column values and
--combine into an HTML cell string using COALESCE
SET @ROW=''''
SET @exec_str='' SELECT @COLOUT=COALESCE(@COLOUT + ''''</td>'''','''''''') + ''''<td>'''' + Cast(IsNull(['' + @ColumnName + ''],'''''''') as nvarchar(max)) from #CustomTable2HTML ''
IF @DEBUG=1 PRINT ''@exec_str: '' + @exec_str
EXEC sp_executesql
@exec_str,
@ParmDefinition,
@COLOUT=@ROW OUTPUT
SET @HTMLROWS =@HTMLROWS + ''<tr>'' + ''<td>'' + @ColumnName + ''</td>'' + @ROW + ''</tr>''
IF @DEBUG=1 SELECT @ROW as ''Current Row''
IF @DEBUG=1 SELECT @HTMLROWS as ''HTML so far..''
FETCH NEXT FROM col INTO @ColumnName
END
CLOSE col
SET @OUTPUT=''''
IF @maxrows>0
SET @OUTPUT= ''<table ' + @TBL_STYLE + '>'' + @HTMLROWS + ''</table>''
DEALLOCATE col
'
END
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
我找到了另一种方法,达到了我的目的
CREATE PROC [dbo].[spQueryToHtmlTable]
(
@query nvarchar(MAX),
@orderBy nvarchar(MAX) = NULL,
@html nvarchar(MAX) = NULL OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
IF @orderBy IS NULL BEGIN
SET @orderBy = ''
END
SET @orderBy = REPLACE(@orderBy, '''', '''''');
DECLARE @realQuery nvarchar(MAX) = '
DECLARE @headerRow nvarchar(MAX);
DECLARE @cols nvarchar(MAX);
SELECT * INTO #dynSql FROM (' + @query + ') sub;
SELECT @cols = COALESCE(@cols + '', '''''''', '', '''') + ''['' + name + ''] AS ''''td''''''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET @cols = ''SET @html = CAST(( SELECT '' + @cols + '' FROM #dynSql ' + @orderBy + ' FOR XML PATH(''''tr''''), ELEMENTS XSINIL) AS nvarchar(max))''
EXEC sys.sp_executesql @cols, N''@html nvarchar(MAX) OUTPUT'', @html=@html OUTPUT
SELECT @headerRow = COALESCE(@headerRow + '''', '''') + ''<th>'' + name + ''</th>''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET @headerRow = ''<tr>'' + @headerRow + ''</tr>'';
SET @html = ''<table border="1">'' + @headerRow + @html + ''</table>'';
';
EXEC sys.sp_executesql @realQuery, N'@html nvarchar(MAX) OUTPUT', @html=@html OUTPUT
END
GO
DECLARE @html nvarchar(MAX);
EXEC spQueryToHtmlTable @html = @html OUTPUT, @query = N'SELECT * FROM sometable';
@html包含html输出,以便您可以对html重新格式化执行操作
例如:
select @htmlTable = Concat('<html>
<style>
table {
border-collapse: collapse;
width: 50%;
}
td, th {
border: 1px solid #B8B8B8;
text-align: left;
padding: 8px;
}
thead {
color:white;
}
</style>
<body>
<table>
<tr>
<th bgcolor="#B8B8B8">col1</th>
<th bgcolor="#B8B8B8">col2</th>
<th bgcolor="#B8B8B8">col3</th>
</tr>',substring(@html,charindex('</tr>',@html,1)+5,len(@html)),'</body></html>')
感谢您的回答。这是因为存储过程的返回值始终为int。文档中已明确说明了这一点。如果要返回值,则需要使用输出参数。但你的程序令人难以置信。我可以在看不到您的过程代码的情况下告诉您,这很容易受到sql注入的攻击。你需要重新思考这个问题。您应该创建一个内联表值函数。这样您就不会传入要运行的查询。作为运行查询的结果返回html。类似于Exec someprocedure“Select*from dbo.Table”的内容看起来非常可疑地对SQL注入开放。
select @htmlTable = Concat('<html>
<style>
table {
border-collapse: collapse;
width: 50%;
}
td, th {
border: 1px solid #B8B8B8;
text-align: left;
padding: 8px;
}
thead {
color:white;
}
</style>
<body>
<table>
<tr>
<th bgcolor="#B8B8B8">col1</th>
<th bgcolor="#B8B8B8">col2</th>
<th bgcolor="#B8B8B8">col3</th>
</tr>',substring(@html,charindex('</tr>',@html,1)+5,len(@html)),'</body></html>')