[英]Selecting SQL Column from Value of Parameter
我有一个包含CR_Name,CV_Name,IC_Name等列标题的表。 我正在尝试编写一个查询,以便如果@p参数设置为'CR',我的选择查询将拉出CR_Name列以及我希望以CR开头的任何其他列。
我已经尝试过以下但它失败了。 有可能,如果可能,怎么样?
declare @p char(2) = 'CR'
select
@p_name --I want this to be the 'CR_name' column
from table
where @p_status = 0 --I want this to be the CR_status column
如果不使用动态SQL(也就是生成-SQL-from-string-concatenation ,这本质上是危险的),则无法在T-SQL中参数化参数。 只需选择所有列并更改应用程序代码中的读取逻辑。
我注意到在查询中选择列非常便宜(除非它是一个大的二进制列,如varbinary(8000)
或其他东西)。
您的问题还询问有条件的WHERE
子句。 不幸的是(据我所知,截至2019年3月)SQL Server的查询优化器仍然没有正确地优化某些模式,比如match-always-if-parameter-is-null模式,但是如果你的表不是高负载的那可能没关系。
像这样:
DECLARE @param1 int = NULL
DECLARE @param2 varchar(50) = 'john smith'
DECLARE @param3 float = 123
SELECT
CR_name,
CV_name,
IC_name
FROM
...
WHERE
( @param1 IS NULL OR CR_name = @param1 )
AND
( @param2 IS NULL OR CV_name = @param2 )
AND
( @param3 IS NULL OR IC_name = @param3 )
您要做的事情是非常不受推荐的,并且暗示您的架构设计可能存在严重缺陷。 如果您提供更多详细信息,则可能有人建议替代方案。 要回答您的问题,您可以尝试以下方法:
declare @p char(2) = 'CR', @SQL VARCHAR(4000);
SET @SQL =
'select '
+ @p
+ '_name from table where '
+ @p + '_status = 0;'
EXECUTE (@SQL);
HTH
你可以通过使用动态SQL来实现这一目标。
create table dbo.Table1
(
CR_Name nvarchar(50),
CV_Name nvarchar(50),
IC_Name nvarchar(50),
CR_Text nvarchar(50)
)
-- declare parameters
declare @p char(2) = 'CR';
declare @p1 TABLE
(
param char(3)
);
insert into @p1
values (concat(@p,'%'));
-- create the skeleton of your query
declare @skeleton nvarchar(max) =
'SELECT <cols>
FROM dbo.table1 AS t;';
-- dynamically get the columns from the table metadata in sql server
declare @sql nvarchar(max) = (
select
REPLACE(@skeleton, '<cols>', cols.cols)
from
sys.objects so
inner join
sys.tables ta on so.object_id = ta.object_id
inner join
sys.schemas sc on ta.schema_id = sc.schema_id
cross apply
(
select
string_agg('t.[' + cols.name + ']',', ') as cols
from
sys.columns cols
left join sys.index_columns ic on ic.index_column_id = cols.column_id and ic.object_id = cols.object_id
left join sys.indexes idx on ic.index_id = idx.index_id and idx.object_id = cols.object_id
-- here we decide, which columns to pick
inner join @p1 para on cols.name like para.param
where
cols.object_id = so.object_id
) cols (cols)
where
so.name = 'table1' and so.type = 'U' and sc.name = 'dbo');
这里的主要困难是还包括动态列过滤器子句,因为您不希望完全匹配,而是需要LIKE行为
然后您可以使用以下命令执行查询:
-- DEBUG
--print(@sql);
--TSA: execute the generated statement
exec sp_executesql @sql;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.