簡體   English   中英

SQL:選擇要從存儲過程返回的不同列

[英]SQL: select different columns to be returned from a stored procedure

假設我有一個包含幾列的mytable表(這並不完全正確,請參見Edit):

mytable
id    data        description          created_at      viewed_times
1      10        'help wanted'      '20180101 04:23'       45
2      20    'customer registered'  '20180504 03:12'        1
...

我創建了一個存儲過程,該存儲過程從該表返回數據。 問題是有時我需要它僅返回iddata列,有時我需要其他信息,例如descriptioncreated_at等。

我的想法是創建三個虛擬變量@ @display_description ,@ @display_created_date@display_viewed_times 當虛擬變量等於1時,我顯示相應的列。 例如,對於命令

exec my_procedure @display_description = 1

我希望輸出

id    data        description        
1      10        'help wanted'      
2      20    'customer registered'  
...

我在程序中如何實現它是:

if @display_description = 1
    select id, data, description from mytable
else 
    select id, data from mytable

問題是,如果我想擁有3個開關(每列一個),則必須在if語句中寫入8個條件。 (我的select語句是一個復雜的語句。此外,如果要顯示它們,則必須計算某些列,如viewed_times 。因此,編寫許多if語句會使查詢非常笨拙,我想避免這種情況)

有沒有一種簡單的方法可以根據開關選擇列? 如果沒有,您建議采用哪種方法從存儲過程中返回不同數量的列?

編輯:對不起,我很遺憾該表mytable已經存在所有列。 事實並非如此,其中一些列必須在顯示之前進行計算。 例如,列“ viewed_times ”不存在。 要顯示它,我需要執行以下操作:

if @display_description = 1
    ~ several selects to calculate the column viewed_times ~
    select id, data, description from mytable join table in which I just calculated the viewed_times column
else 
    select id, data from mytable

計算這些列很耗時,並且僅當我需要顯示這些列時,我才想這樣做。

這就是為什么動態SQL可能無法工作的原因

更新:我接受了動態SQL的答案,但是我做了以下工作:

if @display_viewed_times = 1
begin   
    ~ calculate column viewed_times ~
    update my_table 
    ~ add column viewed_times to the table my_table ~
end

對於每個可選列。 然后我使用返回表

select * from my_table

這給我不同數量的列,具體取決於開關

一種方法是使用動態SQL。 這是偽SQL,因為這里沒有信息來獲得完整答案。 它也未經測試,因為我沒有太多/任何數據可以對此進行實際測試。

--Your input parameters
DECLARE @description bit, @createdate bit, @viewedtimes bit /*...etc...*/;

--Now the SP
DECLARE @SQL nvarchar(MAX);

SET @SQL = N'SELECT ' +
           STUFF(CONCAT(N','+ NCHAR(10) + N'       ' + CASE WHEN @description = 1 THEN QUOTENAME(N'description') END,
                        N','+ NCHAR(10) + N'       ' + CASE WHEN @createdate = 1 THEN QUOTENAME(N'created_at') END,
                        N','+ NCHAR(10) + N'       ' + CASE WHEN @viewedtimes = 1 THEN QUOTENAME(N'viewed_times') END),1,9,N'') + NCHAR(10) +
           N'FROM YourTable' + NCHAR(10) + 
           N'WHERE...;';
PRINT @SQL; --your best debugging friend.
EXEC sp_executesql @SQL /*N'@someParam int', @someParam = @inParam*/;

使用Dyanmic SQL時,請確保正確設置查詢的參數。 不要連接您的字符串!!!

例如,正確的格式應為N'WHERE yourColumn = @yourParam AND OtherColumn = @otherParam' ,然后在sp_executesql提供@yourParam@otherParam的值(正如我在注釋中所展示的)。

但是,請勿執行以下操作: N'WHERE yourColumn = ''' + @myParam + N''' AND otherColumn = ' + CONVERT(varchar(5),@secondParam) 這將對SQL注入開放(不是您的朋友)。

我將存儲過程更改為表值函數,並修改外部的“選擇自”。

因此,例如:

if($value1 === 1)
  $sql = "SELECT c1, c2 FROM dbo.my_udf";
elseif($value1 ===2)
  $sql = "SELECT c1, c3, c4 FROM dbo.my_udf";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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