所以我有一个查询,当我运行时会给我另一个表中列的名称。我要查询的表是我们软件中用户的列配置。它可以从显示3列更改为20列。该表将实际列的名称存储在数据库中。然后,我希望能够仅从该表中获取数据并仅基于返回的那些列名来查询另一个表。我很困惑如何做到这一点,因此当我为不同的用户运行查询时,查询将仅捕获他们保存在配置中的列。
我的第一个查询
SELECT field_name
FROM list_config
WHERE list_config.config_name = 'username'
AND list_config.visible = 'Y';
返回列名:
field_name (header)
create_date
customer_id
id
update_date
update_user_id
short_description
ops_note
create_user_id
resp_user_id
activity_status_id
然后我只想查询表work_order
中仅由第一次查询产生的这些列。
我还是SQL的新手,任何帮助都很棒。我已经尝试过弄乱变量和一些过程,但是我现在还不够了解。
答案 0 :(得分:1)
这是未经测试的,但是,这应该可以为您带来帮助:
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT ' +
STUFF((SELECT N',' + NCHAR(13) + NCHAR(10) +
N' ' + QUOTENAME(field_name)
FROM list_config
WHERE list_config.config_name = 'username'
AND list_config.visible = 'Y'
--ORDER BY ??? --without an ORDER BY the order of the columns will be random/unpredictable
FOR XML PATH(N''),TYPE).value(N'.','nvarchar(MAX)'),1,10,N'') + NCHAR(13) + NCHAR(10) +
N'FROM work_order;';
--PRINT @SQL; --your debugging best friend
EXEC sp_executesql @SQL;
如果需要传递参数,请确保参数化sp_execute
语句; 请勿将参数值插入动态语句。
如果要验证列名是真实列名,则可以使用EXISTS
:
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT ' +
STUFF((SELECT ',' + NCHAR(13) + NCHAR(10) +
N' ' + QUOTENAME(lc.field_name)
FROM list_config lc
WHERE lc.config_name = 'username'
AND lc.visible = 'Y'
AND EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = lc.field_name
AND C.TABLE_NAME = N'Work_order')
--ORDER BY ???
FOR XML PATH(N''),TYPE).value(N'.','nvarchar(MAX)'),1,10,N'') + NCHAR(13) + NCHAR(10) +
N'FROM work_order;';
--PRINT @SQL; --your debugging best friend
EXEC sp_executesql @SQL;
此答案的工作方式是以“定界”格式构建所有列的列表。因此,真正的“魔术”位于FOR XML PATH
中,因此我们将从子查询开始。
FOR XML PATH
基本上按照提示进行操作,它将结果集转换为XML。我们可以使用此功能来连接表work_order
的结果集中的所有值。我给每个值加上N',' + NCHAR(13) + NCHAR(10) + N' '
(这很重要)。这似乎有点奇怪(有些仅使用','
),所以我将进行解释。逗号是简单的逗号,在每个列名之间我们需要其中之一。 NCHAR(13) + NCHAR(10)
是回车符(Unicode字符13)和换行符(Unicode字符10)。然后我们有一些空白。我这样做纯粹是为了格式化,格式化的动态SQL比格式化不好的 更容易解决问题。
然后我们有STUFF
。 STUFF
用于删除field_name
的每个值的第一个前缀(这就是为什么我说作为前缀很重要的原因)。 STUFF
的第二个参数(在这种情况下为1
)是开始替换的位置,第三个参数是要替换的字符数(因此,字符1-10)。最后一个参数是用(''
替换那些字符的内容。这样就用N',' + NCHAR(13) + NCHAR(10) + N' '
替换了第一个前缀(''
)。
答案 1 :(得分:0)
这是另一种方法(未经测试)
declare @query nvarchar(1000) = ''
select @query = @query+',['+field_name+']'
FROM list_config
WHERE list_config.config_name = 'username'
AND list_config.visible = 'Y';
set @query =substring(@query,2,len(@query))
set @query ='select '+@query + ' from work_order'
exec (@query)
您可以以此构建任何类型的脚本