简体   繁体   English

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

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

so i have a query that when i run gives me the names of the columns in another table. 所以我有一个查询,当我运行时给我另一个表中列的名称。 The table i am querying is the user's column configuration in our software. 我要查询的表是我们软件中用户的列配置。 it can change from showing 3 to 20 columns. 它可以从显示3列更改为20列。 The table stores the names of the actual columns in the database. 该表将实际列的名称存储在数据库中。 i then want to be able to take the data from that table and query the other table based only on those column names that were returned. 然后,我希望能够仅从该表中获取数据并仅基于返回的那些列名来查询另一个表。 i'm stumped on how to do it so that as i run the query for different users the query will catch only the columns they have saved in their config. 我很困惑如何做到这一点,所以当我为不同的用户运行查询时,查询将仅捕获他们已保存在配置中的列。

my first query: 我的第一个查询:

SELECT field_name
FROM list_config
WHERE list_config.config_name = 'username'
  AND list_config.visible = 'Y';

returns the column names: 返回列名:

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

i then want to query the table work_order for only these columns produced by the first query. 然后,我只想查询表work_order中第一个查询产生的这些列。

i'm still new to SQL any help would be awesome. 我对SQL还是很陌生,任何帮助都很棒。 i've tried messing around with variables and some procedures but i just don't know enough at this point in time. 我已经尝试过弄乱变量和一些过程,但是我现在还不足够。

This is untested, however, this should get you what you are after: 这未经测试,但是,这应该可以为您带来所需要的:

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;

If you need to pass parameters, then make sure you parametrise your sp_execute statement; 如果需要传递参数,请确保参数化sp_execute语句。 do not inject the parameter values into your dynamic statement. 不要将参数值注入动态语句中。

If you want to validate the the column names are real column names, you can use an EXISTS : 如果要验证列名是真实列名,则可以使用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;

How this answer works is that it builds a list of all the columns in a "delimited" format. 该答案的工作方式是以“定界”格式构建所有列的列表。 The real "magic", is therefore in FOR XML PATH , so we'll going to start there with the subquery. 因此,真正的“魔术”位于FOR XML PATH ,因此我们将从子查询开始。

FOR XML PATH basically does what is says on the tin, it turns the result set into XML. FOR XML PATH基本上执行了上面所说的,将结果集转换为XML。 We can use this functionality to concatenate all the values from the result set from the table work_order . 我们可以使用此功能来连接来自表work_order的结果集中的所有值。 I prefix (this is important) every value with N',' + NCHAR(13) + NCHAR(10) + N' ' . 我为每个值加上N',' + NCHAR(13) + NCHAR(10) + N' ' (这很重要)。 This might seem a bit strange (some only use ',' ), so I'll explain. 这似乎有些奇怪(有些仅使用',' ),所以我将进行解释。 the comma is the easy one, between each column name we need one of those. 逗号是简单的逗号,在每个列名之间我们需要其中之一。 NCHAR(13) + NCHAR(10) is a carriage return (unicode character 13) and a line break (unicode character 10). NCHAR(13) + NCHAR(10)是回车符(Unicode字符13)和换行符(Unicode字符10)。 Then we have some white space. 然后我们有一些空白。 I do this purely for formatting, as well formatted dynamic SQL is much easier to trouble shoot than poorly formatted. 我格式化这样做纯粹,以及格式化动态SQL是麻烦拍摄容易比格式不正确。

Then we have STUFF . 然后我们有STUFF There STUFF is used to remove the first prefix for each value of field_name (this is why I said that it being the prefix is important). 那里有STUFF用于删除field_name每个值的第一个前缀(这就是为什么我说作为前缀很重要的原因)。 STUFF 's second parameter ( 1 in this case) is the position to start a replacement at, and the 3rd is how many characters to replace (so, characters 1 - 10). STUFF的第二个参数(在本例中为1 )是开始替换的位置,第三个参数是要替换的字符数(因此,字符1-10)。 This final parameter is what to replace those characters with ( '' ). 最后一个参数是用( ''替换那些字符'' )。 So that replaces the first prefix ( N',' + NCHAR(13) + NCHAR(10) + N' ' ) with '' . 因此将第一个前缀( N',' + NCHAR(13) + NCHAR(10) + N' ' )替换为''

This is another approach (This is untested) 这是另一种方法(未经测试)

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)

you can build any kind of script with this 你可以用这个建立任何种类的脚本

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

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