我想使用基于表名作为参数的'stuff'函数生成sql代码
这有效:
declare @sql as nvarchar(max);
select @sql = stuff((SELECT distinct [Site]
FROM [ProcterGamble_analytics].[dbo].DATA_table
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 0, '');
exec(@sql);
我希望做一些像
这样的事情declare @presql as nvarchar(max), @sql as nvarchar(max), @table as nvarchar(max);
SET @table = 'DATA_table';
select @presql = 'SELECT distinct [Site]
FROM [ProcterGamble_analytics].[dbo].' + @table
select @sql = stuff((@presql
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 0, '');
exec(@sql);
答案 0 :(得分:1)
您的sql
语句对于什么是字符串以及生成字符串的代码是多么困惑。我认为这会奏效:
select @sql = 'select stuff((' + @presql + '
FOR XML PATH(''''), TYPE
).value(''.'', ''NVARCHAR(MAX)'')
, 1, 0, '''')';
当您执行@sql
时,它应该返回值。
答案 1 :(得分:1)
我认为你很难创建XML而不是使用分隔符连接不同的网站并使用stuff函数来替换第一个分隔符。
我通常喜欢编写可以重用的代码。我将数据库,模式,表和列名称作为输入传递。我使用SYSNAME作为首选变量。
注意到我使用了一个组而不是另一个组。在这个例子中,它们是相同的。但是,分组可以有时节省您的时间。
查看处理指令命令。将动态字符串转储为XML文档。真的很酷?
--
-- Generate a list in XML
--
-- Pass variables w/input
DECLARE @my_database SYSNAME = 'AdventureWorks2012';
DECLARE @my_schema SYSNAME = 'Production';
DECLARE @my_table SYSNAME = 'Product';
DECLARE @my_column SYSNAME = 'Name';
-- Create the dynamic SQL (xml output_)
DECLARE @sql_stmt1 varchar(max) = '';
SET @sql_stmt1 += 'SELECT [' + @my_column + '] FROM [' +
@my_database + '].[' + @my_schema + '].[' + @my_table + '] ';
SET @sql_stmt1 += 'GROUP BY [' + @my_column + '] ';
SET @sql_stmt1 += 'ORDER BY [' + @my_column + '] ';
SET @sql_stmt1 += 'FOR XML PATH (''''), ROOT('''+ @my_column + 's'')';
-- Cool instruction ?
SELECT @sql_stmt1 as [processing-instruction(TSQL)] FOR XML PATH
-- Show my data
EXEC(@sql_stmt1);
简而言之,这里以冒险作品的输出为例。只需更改案例的输入即可。
如果您想要一个分隔列表,我使用派生表D重复代码并将STUFF()函数应用于结果字段X.
--
-- Generate a delimited list
--
-- Pass variables w/input
DECLARE @my_database SYSNAME = 'AdventureWorks2012';
DECLARE @my_schema SYSNAME = 'Production';
DECLARE @my_table SYSNAME = 'Product';
DECLARE @my_column SYSNAME = 'Name';
-- Create the dynamic SQL
DECLARE @sql_stmt varchar(max) = '';
SET @sql_stmt += 'SELECT STUFF(X, 1, 1, '''') AS LIST FROM ';
SET @sql_stmt += '( SELECT '','' + [' + @my_column +
'] FROM [' + @my_database + '].[' + @my_schema + '].[' + @my_table + '] ';
SET @sql_stmt += 'GROUP BY [' + @my_column + '] ';
SET @sql_stmt += 'ORDER BY [' + @my_column + '] ';
SET @sql_stmt += 'FOR XML PATH ('''') ) AS DT (X) ';
-- Cool instruction ?
SELECT @sql_stmt as [processing-instruction(TSQL)] FOR XML PATH
-- Show my data
EXEC(@sql_stmt);
我希望这能回答你的问题,如果没有,请回信。
答案 2 :(得分:0)
您真的不需要@presql
部分,只需要加倍单引号,以便在处理动态部分时正确处理它们:
DECLARE @sql AS NVARCHAR(MAX)
,@table AS NVARCHAR(MAX) = 'DATA_table';
SET @sql = 'stuff(( SELECT distinct [Site]
FROM [ProcterGamble_analytics].[dbo].' + @table + '
FOR XML PATH(''''), TYPE
).value(''.'', ''NVARCHAR(MAX)'')
, 1, 0, '''')';
EXEC(@sql);
测试动态SQL的一个好方法是使用PRINT(@sql);
EXEC
来确认将要执行的代码是你想要的代码。