我正在使用MS SQL Server 2008.我正在尝试创建一个存储过程来将(可能)几行数据(答案)合并到目标表的单行中。这使用了答案表中的“table_name”字段和“column_name”字段。数据看起来像这样:
answers table
--------------
id int
table_name varchar
column_name varchar
answer_value varchar
因此,目标表(插入/更新)将来自'table_name'。来自anwsers的每一行都将填充目标表上的一列。
table_name_1 table
--------------
id int
column_name_1 varchar
column_name_2 varchar
column_name_3 varchar
etc...
请注意,可以在每个目标表上插入许多列(column_name_1 ... 2 ... 3)中的目标表(来自答案表的变量:table_name_1,table_name_2,table_name_3等)。
我想过使用WHILE语句循环遍历答案表。这可以构建一个变量,它将是目标表的插入/更新语句。然后以某种方式执行这些语句。我也注意到Merge看起来可能有助于解决这个问题(select / update / insert),但我的MS SQL存储过程体验非常少。有人可以建议这个问题的策略或解决方案吗?
Note 6/23/2014:我正在考虑使用单个Merge语句,但我不确定它是否可行。
答案 0 :(得分:1)
我可能遗漏了一些东西,但解决问题的基本思路是使用元编程,就像动态旋转一样。
在这种特殊情况下,还有另一层使解决方案更加困难:结果需要在不同的执行中而不是分组。
可能解决方案的主干是
DECLARE @cols AS NVARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)
--using a cursor on SELECT DISTINCT table_name FROM answers iterate:
--*Cursor Begin Here*
--mock variable for the first value of the cursor
DECLARE @table AS NVARCHAR(MAX) = 't1'
-- Column list
SELECT @cols = STUFF((SELECT distinct
',' + QUOTENAME(column_name)
FROM answers with (nolock)
WHERE table_name = @table
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '')
--Query definition
SET @query = '
SELECT ' + @cols + '
INTO ' + @table + '
FROM (SELECT column_name, answer_value
FROM answers
WHERE table_name = ''' + @table + ''') b
PIVOT (MAX(answer_value) FOR column_name IN (' + @cols + ' )) p '
--select @query
EXEC sp_executesql @query
--select to verify the execution
--SELECT * FROM t1
--*Cursor End Here*
省略了游标定义,因为我不确定它是否适用于SQLFiddle
除了动态数据透视表的模板之外,列表列表将按新表名称进行过滤,在查询定义中有SELECT ... INTO
而不是SELECT
。
此脚本不考虑数据库中已存在的表,如果有可能将查询分为两部分:
SET @query = '
SELECT TOP 0 ' + @cols + '
INTO ' + @table + '
FROM (SELECT column_name, answer_value
FROM answers
WHERE table_name = ''' + @table + ''') b
PIVOT (MAX(answer_value) FOR column_name IN (' + @cols + ' )) p '
创建没有数据的表(如果需要)和
SET @query = '
INSERT INTO ' + @table + '(' + @cols + ')'
SELECT ' + @cols + '
FROM (SELECT column_name, answer_value
FROM answers
WHERE table_name = ''' + @table + ''') b
PIVOT (MAX(answer_value) FOR column_name IN (' + @cols + ' )) p '
或MERGE
插入/更新表格中的值
另一种可能性是DROP
并重新创建每个表格。
答案 1 :(得分:0)
方法我解决了这个复杂的问题: