全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:7131
推到 Plurk!
推到 Facebook!

sql 的 locate 用法

答題得分者是:Justmade
P.D.
版主


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

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-03-13 13:42:14 IP:61.66.xxx.xxx 未訂閱
請問各位! 在 SQL 語法中, 有沒有類似 Locate(或seek) 的用法, 也就是說當我希望找到 某一筆記錄後指標移到那裡仍是現出全部的記錄出來的功能(不是 where 只能抓取一筆記錄), 除了 locate 以外, 效能可以更好的不知有沒有? ps:不可以用 bookmark, 因為query.close後 bookmark就不見, 再open都不對了, 而且如果有 order by的話, bookmark根本都失效
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-03-13 13:51:07 IP:211.74.xxx.xxx 未訂閱
Query1.Locate('客戶編號',Edit1.text,[loPartialKey]) ; TRY TRY SEE
timhuang
尊榮會員


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-03-13 14:00:07 IP:211.76.xxx.xxx 未訂閱
請問你要問的是 sql 的語法嗎? SQL 僅能針對你要查詢的條件進行查詢而不能負責將記錄指標移動到該筆資料, 不過有一種方式可以達到你要的功能, 就是自行串出結果集, 這種方式可以把 你要的資料帶出在前面, 其餘的資料在後面的方式, 如此一來在 query.open 回 傳時的結果集裡, 前面的資料就是你要的... 例如: 原來的 sql command 為 : select cust_id, cust_name from customer 改為 select cust_id, cust_name from customer where cust_id like '%EX%' union select cust_id, cust_name from customer where cust_id not like '%EX%' 不知道是不是你要的..
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-03-13 14:04:58 IP:61.219.xxx.xxx 未訂閱
引言: 請問各位! 在 SQL 語法中, 有沒有類似 Locate(或seek) 的用法, 也就是說當我希望找到 某一筆記錄後指標移到那裡仍是現出全部的記錄出來的功能(不是 where 只能抓取一筆記錄), 除了 locate 以外, 效能可以更好的不知有沒有? ps:不可以用 bookmark, 因為query.close後 bookmark就不見, 再open都不對了, 而且如果有 order by的話, bookmark根本都失效
如果你是要用SQL 辦到, 也就是說在資料庫端完成, 用 Store Procedure return cursor 可能可以, 參考看看... /* Free 和 Create 一樣重要 */
P.D.
版主


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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-03-16 12:09:16 IP:61.66.xxx.xxx 未訂閱
引言: 請問你要問的是 sql 的語法嗎? SQL 僅能針對你要查詢的條件進行查詢而不能負責將記錄指標移動到該筆資料, 不過有一種方式可以達到你要的功能, 就是自行串出結果集, 這種方式可以把 你要的資料帶出在前面, 其餘的資料在後面的方式, 如此一來在 query.open 回 傳時的結果集裡, 前面的資料就是你要的... 例如: 原來的 sql command 為 : select cust_id, cust_name from customer 改為 select cust_id, cust_name from customer where cust_id like '%EX%' union select cust_id, cust_name from customer where cust_id not like '%EX%' 不知道是不是你要的..
這個方法雖然可以帶出所有記錄, 但我要的是必須順序仍保持原來的樣子, 記錄指標不可以變動!
P.D.
版主


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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-03-16 12:10:49 IP:61.66.xxx.xxx 未訂閱
引言: 如果你是要用SQL 辦到, 也就是說在資料庫端完成, 用 Store Procedure return cursor 可能可以, 參考看看... /* Free 和 Create 一樣重要 */
Mickey版主! 如何用StoreProcedure 完成傳回 cursor , 是否有參考資料可以觀摩? 謝謝!
timhuang
尊榮會員


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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-03-16 14:43:05 IP:61.221.xxx.xxx 未訂閱
引言:
引言: 原來的 sql command 為 : select cust_id, cust_name from customer 改為 select cust_id, cust_name from customer where cust_id like '%EX%' union select cust_id, cust_name from customer where cust_id not like '%EX%' 不知道是不是你要的..
這個方法雖然可以帶出所有記錄, 但我要的是必須順序仍保持原來的樣子, 記錄指標不可以變動!
那就得利用一個虛擬欄位來達成了. 作法如下: select cust_id, cust_name, case when cust_id like '%EX%' then 1 else 0 end as condition1 from customer 接下來再利用 locate('condition1', 1, []) 來取得資料. 如此一來即可達成 p.d. 兄要的順序, 也可以提升 locate 的速度, 將條件由 server 端處理, client 就僅須利用一個虛擬欄位來進行 locate 的動作!!
P.D.
版主


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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-03-17 00:44:57 IP:61.66.xxx.xxx 未訂閱
timhuang 兄! 我試了你的方式, 可能我用 Interbase, 似乎不接受 case when ... 的用法 出現 Dyanmic SQL error 'when'.... 不知你提供的這個SQL語法, 是用在那種SQL Language?
cmj
高階會員


發表:15
回覆:242
積分:226
註冊:2002-06-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-03-17 02:12:12 IP:211.76.xxx.xxx 未訂閱
我想你的問題是使用QUERY來對SQL SERVER之TABLE做維護設計程式 提供個人針對單一SQL SERVER之單一table之維護系統經驗 使用QUERY1 DBGRID,DBNAVIGATOR,DATASOURCE,DBEDIT等元件 使用QUERY10作查詢用 1.用tquery select指令抓某一範圍資料錄,到底抓多少筆記錄範圍而設計者針對TABLE用途性質決定,不限定範圍是較差的做法 2.新增修改刪除單一資料使用DBNAVIGATOR按鈕操作, 3.查詢使用QUERY1.LOCATE查QUERY內資料錄,若查不到資料再QUERY10 SQL指令查 資料庫內之資料,再由QUERY1重新SELECT含查到記錄之範圍資料錄,最後QUERY1.LOCATE此筆查詢資料. 考慮晝面顯示及BOOKMARK問題,以上是我認為較佳做法若是使用純SQL較難達到你所想要的.
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-03-17 08:32:34 IP:61.219.xxx.xxx 未訂閱
引言:
引言: 如果你是要用SQL 辦到, 也就是說在資料庫端完成, 用 Store Procedure return cursor 可能可以, 參考看看... /* Free 和 Create 一樣重要 */
Mickey版主! 如何用StoreProcedure 完成傳回 cursor , 是否有參考資料可以觀摩? 謝謝!
你用 InterBase ? 抱歉,我這種資料系統不熟. 看你的需求,再搭配使用
timhuang
尊榮會員


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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-03-17 09:45:24 IP:211.76.xxx.xxx 未訂閱
引言: 我試了你的方式, 可能我用 Interbase, 似乎不接受 case when ... 的用法 出現 Dyanmic SQL error 'when'.... 不知你提供的這個SQL語法, 是用在那種SQL Language?
這個語法是用在 MS SQL Server 下的. 是屬條件式的傳回值. interbase 的話, 可能沒有支援, 我再找找看有沒有相關的語 法可以替代..
P.D.
版主


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

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-03-17 17:53:15 IP:211.78.xxx.xxx 未訂閱
引言: 我想你的問題是使用QUERY來對SQL SERVER之TABLE做維護設計程式 提供個人針對單一SQL SERVER之單一table之維護系統經驗 使用QUERY1 DBGRID,DBNAVIGATOR,DATASOURCE,DBEDIT等元件 使用QUERY10作查詢用 1.用tquery select指令抓某一範圍資料錄,到底抓多少筆記錄範圍而設計者針對TABLE用途性質決定,不限定範圍是較差的做法 2.新增修改刪除單一資料使用DBNAVIGATOR按鈕操作, 3.查詢使用QUERY1.LOCATE查QUERY內資料錄,若查不到資料再QUERY10 SQL指令查 資料庫內之資料,再由QUERY1重新SELECT含查到記錄之範圍資料錄,最後QUERY1.LOCATE此筆查詢資料. 考慮晝面顯示及BOOKMARK問題,以上是我認為較佳做法若是使用純SQL較難達到你所想要的.
我要這個功能是因為我做了一個萬用的DBGrid Browser, 可以有鎖定欄位(fix coloumn), 排序(order by..), 匯出資料(export), 自定要顯示的欄位等等十數 種功能集一身的dbgrid, 其中有一項排序, 當我在某一個欄位上想依這個欄位 值做order 動作, 因為我使用 query資料庫, 所以在重新設定 sql 語法(order by xxxx)之後再open資料庫, 記錄指標會移到最上面, 而無法停留在我原先排序 前所在的那一筆, 雖然使用 locate可以找到我要的記錄(目前也是如此做), 但 我的資料庫有數十萬筆, locate一執行就完蛋了, 泡杯咖啡喝完了它還在locate , 所以我想是否有SQL語法可以在數秒內完成如同locate一樣的做法, 當然不能 用 where, 因為我還是要可以秀出全部的記錄(依當時在記錄where的條件下, 所以可能只有數十筆, 也可能是全部), 這個介面十分好用, 唯獨這項是令人遺"恨", 不知各位是否有更好的解決方式(不嘗試用temp dbf來做, 因為排序是 隨時會被執行, 資料集也無法掌握有多少筆)!
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-03-17 18:56:09 IP:218.16.xxx.xxx 未訂閱
若你使用 TClientDataSet 的話,是可以直接 Addindex 或 使用 IndexDefs 來排序而不需要重讀資料的。可index 多欄位,某些欄位 accending 某些欄位 decending 也可以,某些 case sensitive 某些不 sensitive 也可以,而且 cursor 不會改變。index 的速度滿快的,因為在 memory 進行。 不過,這兩個做法一般都會先將所有資料 Fetch 進 DataSet 才再即時做 index ,如果你有幾十萬筆資料,娙internet傳送,就.... 若你可接受只針對已存在於 Dataset 的資料排序,亦可以 clonecursor 或 copy Clientdataset.data 到另一clientdataset 來排序。 當然,最理想的是若資料有10萬筆,在重新select order by 後原本選定的資料若排在第 89650 第,就只先回傳第 89600-89700 第資料且定在原本的記錄中,使用者向上移才一點點傳送 89600前的資料,向下移才傳送 89700後的資料。不過,好像還做不到耶.....
cmj
高階會員


發表:15
回覆:242
積分:226
註冊:2002-06-12

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-03-17 20:19:27 IP:211.76.xxx.xxx 未訂閱
對不起我不會引言,我回應P.D.最近疑問 個人經驗是若使用TQUERY元件來做資料維諼,我會用至少兩個假設為TQ1,TQ10 TQ1主要為維護用,是DBGRID,DBEDIT,DATASOURCE所串聯之DataSet TQ10主要是下SQL命令用, 1.首先在一二十萬記錄全部SELECT,速度上不會多慢,但和環境有關不建議不下WHERE條件,若一般基本資料評估不會成長萬筆以上那我不下WHERE,若成長會很多一定下WHERE KEY LIKE :KEY , :KEY自已考量範圍,KEY一定為索引 2.TQ1.OPEN在進畫面執行一次,或是只有在新增一筆記錄後或改變索引才會再OPEN 3.使用LOCATE,一定針對索引,不然會有效能的問題,至於BOOKMARK的問題主要是重OPEN後如何再指到原來記錄,只有一個方法,記住原PRIMARY KEY,再用LOCATE, 速度很快, 4.資料庫快慢問題要是在SELECT時,下SELECT沒有特別秘笈,只有合不合適的指令,至於採用TEMP DB,還是要先SELECT在放入TEMP DB,並不適合資料護使用,TEMP DB應是應用於統計或較複雜處理無法很容易用SQL指令來處理的場合, 5.最後你的做法方向沒錯應是LOCATE是不是索引鍵,還有SELECT的範圍是不是要全部SELECT. 以上是個人經驗,提供參考.
P.D.
版主


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

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-03-18 00:24:19 IP:61.66.xxx.xxx 未訂閱
首先感謝各位網友提供你們的經驗分享, 以下cmj所提的, 我解釋一下, 就本case而言    
引言: 個人經驗是若使用TQUERY元件來做資料維諼,我會用至少兩個假設為TQ1,TQ10 TQ1主要為維護用,是DBGRID,DBEDIT,DATASOURCE所串聯之DataSet TQ10主要是下SQL命令用,
本案中, 因為我是發展一個工具可以如早期在DOS下對記錄做瀏覽功能的工具, 在這工具中主要是查詢用, 但也可以針對查到的記錄排序, 過濾, 匯出等功能
引言: WHERE條件,若一般基本資料評估不會成長萬筆以上那我不下WHERE,若成長會很多一定下WHERE KEY LIKE :KEY , :KEY自已考量範圍,KEY一定為索引
排序目的在於觀看 上下筆的關聯性, 例如找到 姓名 "王二" 往上可以看到 "王一", 往下可看到"王三", 因為是工具, 所以設計上是針對任何的資料集的任何欄位皆可以放到 dbgrid中, 因此index 是不可行, 因為萬一這個資料集有100欄位, 是否要index 100個field(甚至複合索引也做不到), 所以只能考慮用 order, 而where 非必備 所以有可能全部資料, 也有可能是where後的資料集
引言: 2.TQ1.OPEN在進畫面執行一次,或是只有在新增一筆記錄後或改變索引才會再OPEN
當使用者在我安置的排序button點一下, 會重新改寫sql, 當然重新open是沒有 問題, 目前也是這樣做
引言: 3.使用LOCATE,一定針對索引,不然會有效能的問題,至於BOOKMARK的問題主要是重OPEN後如何再指到原來記錄,只有一個方法,記住原PRIMARY KEY,再用LOCATE, 速度很快,
前面有所說過無法用index的理由, 原本我想用bookmark, 但bookmark並非如 早期dbase的record指標是不變的, query.close->query.open, 原先內存的 bookmark指標就已消失, 再指定 query.bookmark:= xxxx, 已經沒有意義, 否 則bookmark我試過十萬筆也花不到一秒, 真的很好用, 如果能解決這個問題, 那 一切問題都沒有了! 至於primary key 方式因為primary key 不允許重覆值, 一旦啟用primary key 那我這個工具就會有所設限, 換句話說 那資料集就必須具備有非重覆性記錄的判斷! 不過本法倒是可以考慮!
引言: 4.資料庫快慢問題要是在SELECT時,下SELECT沒有特別秘笈,只有合不合適的指令,至於採用TEMP DB,還是要先SELECT在放入TEMP DB,並不適合資料護使用,TEMP DB應是應用於統計或較複雜處理無法很容易用SQL指令來處理的場合,
因為我的目的在查詢記錄, 所以當然不會去使用 temp db方式, 因為沒有效率, 這點我是不會考慮! 不知道各位還有沒有解決之道, 我已經找了二年, 還沒有找到我的 "心上人" 發表人 -
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-03-18 09:02:08 IP:218.16.xxx.xxx 未訂閱
DBase / Clipper 數量庫當是每個 Record 是有 Unique 的 Record No 的,Bookmark 當然可行並快速啦 我真的建議你花點時間試試 TClientDataSet ,它增加了不少功能,任何 DataSet 加上 DataSetProvider 都可連上它 我上文所說的 AddIndex / IndexDefs 等不是設計時設定的而是執行時即時做的,適合設計時還不知道數量庫是甚麼架構及使用者想甚樣排序。只要使用者選好排序的數個欄位,每個欄位用 Acc / Dec, 是否 Case Sensitive,就可按使用者的選擇 AddIndex, 之後選用該新 Add 的 index 就好。你還可以記住新增過甚麼 index 讓使用者快速的選他之前增加了的 index 不用重新做。 若數據己讀到 DataSet 創做 Index 排序的時間還好,我昨天試在5000筆記錄向一個長15文字欄位排序約0.7秒,且不會影響 cursor。 TClientDataSet 還提供內部的 Cache update,在你 apply update 前可讓使用者像在用 Office 似的一步一步的 undo。 TClientDataSet 也可以直接輸出 XML,存取成檔案,做 memory table 等 (參考 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=27190) 考慮看看。
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-03-19 11:34:41 IP:61.219.xxx.xxx 未訂閱
我認同 Justmade 的觀點. TQuery -> TDataSetProvider -> TClientDataSet. 到 ClientDataSet 後, DataSet 真的可以"隨你搞", 不過 memory 須夠大才感覺的到它的快速. 補充: 1. TQuery.UniDirectional Property -> True, 應可增快速度. 2. TClientDataSet.SaveToFile 可用 binary file format (*.cds), 速度可能可以比 XML 較快(個人猜想未驗證) /* Free 和 Create 一樣重要 */
P.D.
版主


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

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-03-20 00:06:28 IP:61.66.xxx.xxx 未訂閱
感謝各位鼎立協助, 我大概有個方向, 不過這個月因為案件很趕, 暫時 無法有進一步的測試, 等下個月有空測測看, 再報告結果! 這篇給分很困難, 大家都有份啦, 本著給後進網友支持, Justmade 兄 的功力應該相當高深哦!(從最近回答的討論中),
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-03-20 08:57:14 IP:218.16.xxx.xxx 未訂閱
功力不高啦,很多答案都要都 help / google 找資料再儘可能試驗一下得出的,而 TClientDataSet 是最近常用的所以比較熟。 所以不是功力高,只是比較會找資料罷了,跟這裡眾多高手差遠了。
系統時間:2024-11-23 3:58:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!