繁体   English   中英

如何选择行值作为另一个表的列名?

[英]How to Select Row values as another table's column names?

所以我有一个查询,当我运行时给我另一个表中列的名称。 我要查询的表是我们软件中用户的列配置。 它可以从显示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还是很陌生,任何帮助都很棒。 我已经尝试过弄乱变量和一些过程,但是我现在还不足够。

这未经测试,但是,这应该可以为您带来所需要的:

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' ' )替换为''

这是另一种方法(未经测试)

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)

你可以用这个建立任何种类的脚本

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM