線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2145
推到 Plurk!
推到 Facebook!

如何令Sql語法Where條件為選擇性的?

尚未結案
pedro
尊榮會員


發表:152
回覆:1187
積分:892
註冊:2002-06-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-06-10 10:15:14 IP:210.61.xxx.xxx 未訂閱
請教各位前輩 我用ADOQuery.Params.ParamByName('ItemNo') Sql.Text語法如下
declare @ItemNo char(20)    set @ItemNo= :ItemNo    select ItemNo
from bil1b
where OrdDate= '20050609' and
(case When @ItemNo<>'' then P1_ItemNo=@ItemNo end)
意思是若ItemNo為空字串時,並不想讓ItemNo出現在where條件列裡, 如果有指定才出現 紅色那段語法是錯的,請問我該怎麼做才好? 謝謝您 ................... .楛耕傷稼,楛耘失歲. ...................
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-06-10 11:26:16 IP:61.71.xxx.xxx 未訂閱
引言: 請教各位前輩 我用ADOQuery.Params.ParamByName('ItemNo') Sql.Text語法如下
declare @ItemNo char(20)    set @ItemNo= :ItemNo    select ItemNo
from bil1b
where OrdDate= '20050609' and
(case When @ItemNo<>'' then P1_ItemNo=@ItemNo end)
意思是若ItemNo為空字串時,並不想讓ItemNo出現在where條件列裡, 如果有指定才出現 紅色那段語法是錯的,請問我該怎麼做才好? 謝謝您 ................... .楛耕傷稼,楛耘失歲. ...................
換個想法來做這件事, 如果在 sql 內無法達成, 那就由Delphi來完成
declare @ItemNo char(20)    set @ItemNo= :ItemNo    select ItemNo
from bil1b
where OrdDate= '20050609' and
(case When @ItemNo<>'' then P1_ItemNo=@ItemNo end)
把紅色的部份當成是一個字串 #filter
declare @ItemNo char(20)    set @ItemNo= :ItemNo    select ItemNo
from bil1b
where OrdDate= '20050609' #filter    在Delphi中寫    sqltring:= 'select ItemNo from bil1b where OrdDate= "20050609" #filter';
if Itemno <> '' then StringReplace(sqlstring,'#filter',
   'and (case When @ItemNo<>"" then P1_ItemNo=@ItemNo end)',
   [rfReplaceAll])
else StringReplace(sqlstring,'#filter','',[rfReplaceAll]);
ADOQuery.text.sql:= sqlstring;
if itemno<> '' then ADOQuery.Params.ParamByName('ItemNo'):= .....
如此可以做到更多 sql 無法做到的功能, 同時避免在sql中宣告variable, 增加解譯時的困難度 發表人 - P.D. 於 2005/06/10 11:33:46
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-06-10 12:03:36 IP:220.132.xxx.xxx 未訂閱
Hi, 在資料庫存取中, 使用 parameter 是方便給予查詢條件使用的方法, 很少看到有人這樣使用, 並非說使用方法不正確, 而是會造成維護上的困難, 尤其會讓非熟悉資料庫指令程式設計人員造成困擾, 所以一般有這樣的需求, 會利用組合 sql command 的方式來操作會比較理想, 如同 P.D. 兄的做法即為其一.    言歸正傳, 是否你的做法是可行的呢, 當然囉, 是可行的, 只是指令有誤而已, 記得在 SQL Server 中的 Case when end 語法是一種輸出轉向的指令(output redirect), 也就是並非評估測試指令, 這個觀念清楚後, 要組合你的用法就容易了, 應該這麼寫,    declare @ItemNo char(20)    set @ItemNo= :ItemNo    select ItemNo from bil1b where OrdDate= '20050609' and (P1_ItemNo = case When @ItemNo<>'' then @ItemNo end) or @ItemNo = '' 後面的 or @ItemNo = '' 是為了解決當你的 ItemNo 有賦空值時, 則 where condition 要全滿足的附屬條件, 注意, 因為 case .. 語法僅有輸出轉向功能, 沒有評估測試功能, 所以組合的布林條件式會變得比較複雜, 但就資料庫指令來說, 這樣的指令是沒有效率的哦, 所以最好還是利用重組 sql command 會比較好, 至於怎麼說沒有效率呢? 因為每一列的測試都得經過一次的 case when end 的重導後再和 P1_ItemNo 欄位比對, 當然, 若你有其他必需存在的邏輯時, 則不在此限囉!
pedro
尊榮會員


發表:152
回覆:1187
積分:892
註冊:2002-06-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-06-13 08:41:41 IP:210.61.xxx.xxx 未訂閱
感謝PD和timhuang前輩很詳細的解說 謝謝 我平常都用SQl.Add去組語法,但有時候需去Try User的報表,會建立臨時性的語法,每次重組Sql時,程式碼就要QuotedStr('...')一大堆,很煩,所以暫時先用timhuang大大所演示的辦法... ................... .楛耕傷稼,楛耘失歲. ...................
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-06-13 10:40:47 IP:203.95.xxx.xxx 未訂閱
Hi, 應該還可以再修正一下會更好, 改為不利用 case when 的語法, 因為 case when 在這裡似乎只是一個邏輯式, 改為這樣應該會更好: where OrdDate= '20050609' and (P1_ItemNo = @ItemNo and @ItemNo<>'') or @ItemNo = '' 希望對你的查詢有幫助!
系統時間:2024-06-26 23:33:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!