簡體   English   中英

從參數值中選擇SQL列

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM