亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

多層數據庫開發九:查詢數據庫

2019-11-18 18:11:09
字體:
來源:轉載
供稿:網友
                           第九章 查詢數據庫
  這一章介紹如何用TQuery構件查詢數據庫,如何通過SQL語句檢索、插入、更新和刪除數據。SQL是符合工業標準的關系數據庫語言,既可以用于遠程的基于服務器的數據庫,如Sybase、Oracle、InterBase和Microsoft SQL Server,也可以用于本地數據庫如Paradox、dBASE、FoxPRo和access以及符合ODBC的數據庫。
9.1 有效地使用查詢
  要有效地使用查詢,必須熟悉標準的SQL語言以及所使用的服務器對SQL-92的限制和擴展,同時還要熟悉BDE。
9.1.1 查詢桌面數據庫
  作為一個桌面開發者,應對表格、記錄和字段的概念有所了解,又能熟練地使用TTable構件訪問數據集中的每一條記錄和每一個字段。
還可以使用TTable的范圍和過濾功能在數據集中選擇一部分記錄,前者用于選擇一塊連續的記錄,這些記錄的值在一個特定的范圍內; 后者用于選擇非連續的記錄,這些記錄符合特定的條件。
  所謂查詢,非常類似于過濾,不同的是,查詢要用到TQuery構件和SQL屬性,有時候可能還要用到Params屬性。從功能上講,查詢要比過濾復雜和強大些,這主要體現在:
.可以同時查詢幾個表格
.可以讓查詢結果中只包含部分字段,而過濾將返回所有字段。
  查詢也可以帶參數,此時稱為參數化查詢。所謂參數,類似于變量,它的實際的值由BDE在執行SQL語句之前賦值。參數化查詢的好處是,不需要修改SQL語句,只要修改參數的值,就能執行不同的查詢功能。
  大部分情況下,使用TQuery構件是為了在數據集中選擇一部分字段和記錄,但也可以使用SQL語句實現更新、插入和刪除記錄的功能,這是與TTable構件的一個區別。
9.1.2 查詢遠程數據庫
  要查詢遠程數據庫,必須熟悉SQL語句以及服務器對標準SQL的限制和擴展。
  TQuery構件的SQL屬性用于指定要執行的SQL語句, Params屬性用于提供參數。TQuery構件的功能并不只限于SQL語句和參數,它還是BDE與應用程序之間的接口。
  應用程序可以通過TQuery構件的屬性和方法來操縱SQL語句和參數。TQuery構件最終還是通過SQL Links與遠程服務器進行通訊的,遠程服務器把查詢結果返回給BDE,再由BDE返回給應用程序。
9.2 可以查詢哪些數據庫
  使用TQuery構件可以查詢下列數據庫:
  一是Paradox或dBASE,這是通過BDE內置的Local SQL實現的。Local SQL是SQL-92標準的一個子集,支持大部分DML和DDL。
  二是Local InterBase Server,這是通過InterBase引擎實現的。
  三是遠程數據庫,如Oracle、Sybase、MS-SQL Server、InFormix、DB2和InterBase,不過,必須安裝了相應的SQL Links驅動程序。不同的服務器對標準SQL都有不同的限制和擴展,要查詢遠程數據庫之前,務必要查閱它的有關文檔。
  Delphi 4還支持異構查詢,也就是說,可以同時查詢幾個不同類型的數據庫。
9.3 使用TQuery構件的一般步驟
  第一步是把一個TQuery構件放到數據模塊上,設置它的DatabaseName屬性指定要訪問的數據庫。對于Paradox和dBASE來說,DatabaseName屬性可以設為BDE別名如DBEMOS、DefaultDD、IBLOCAL等,也可以是自定義的別名或者表所在的路徑。
  對于SQL表來說,DatabaseName屬性只能設為BDE別名。如果應用程序使用TDatabase構件來連接數據庫,DatabaseName屬性也可以設為應用程序專用的別名。
  第二步是設置SQL屬性指定要執行的SQL語句,有必要的話還可以設置Params屬性為SQL語句設置參數。
  第三步是把TDataSource構件放到數據模塊上,設置它的DataSet屬性指定TQuery構件。再把TDBGrid構件放到窗體上,設置它的DataSource屬性指定TDataSource構件。
  第四步是執行SQL語句。要執行SQL語句有兩種方式,一是在設計期把Active屬性設為True,程序啟動時將自動執行SQL語句。另一種方式是在運行期調用Open或ExecSQL執行SQL語句。如果希望返回查詢結果,調用Open,如果不需要返回查詢結果,調用ExecSQL。在調用Open或ExecSQL之前,最好先調用Prepare通知服務器作好準備。
  執行SQL語句所返回的查詢結果實際上是數據集中滿足特定條件的記錄所組成的子集,數據庫柵格中只顯示符合特定條件的記錄。
9.4 指定要執行的SQL語句
  可以設置SQL屬性以指定要執行的SQL語句。在設計期,只要把Active屬性設為True,就會自動執行SQL語句。在運行期,首先要調用Prepare通知服務器準備好,然后調用Open或ExecSQL執行SQL函數語句。
9.4.1 概述
  SQL屬性是一個典型的TStrings對象。SQL屬性一般只包含一條完整的SQL語句,但可以分成幾行寫,TQuery構件會自動把幾行字符串合并成一條SQL語句。
  把SQL語句分成幾行寫的好處是,SQL語句的邏輯結構比較清楚,有利于今后維護和調試。所以,SQL語句的SELECT部分和WHERE部分一般都不在同一行上。
  SQL語句可以不帶參數,把字段名稱和值固定在SQL語句中,例如,下面這個SQL語句就是硬寫(Hard-Coded)的:
  SELECT * FROM Customer WHERE CustNo = 1231
  注意:如果要查詢的是本地數據庫,如果SQL語句中的字段名包含空格或其他特殊符號,必須用引號括起來,前面還要加上表格名和小圓點。
  如果用參數的話,查詢就靈活得多,應用程序不需要改寫SQL語句本身,只要修改參數的值,就能使SQL語句執行不同的查詢功能。在執行SQL語句之前,TQuery構件會自動把實際的值替換SQL語句中的參數,即使并沒有顯式地調用Prepare函數。
  下面這條SQL語句是典型的參數化查詢:
  SELECT * FROM Customer WHERE CustNo = :Number
  其中,Number就是一個參數,它的前面必須加冒號。在運行期,應用程序必須提供Number參數的值,每次執行SQL語句時,Number參數的值可以不同。
  參數的值是通過TQuery的Params屬性提供的。
9.4.2 在設計期指定SQL語句
  在設計期,要指定SQL語句,可以在對象觀察器中單擊SQL屬性邊上的省略號按鈕,彈出一個字符串列表編輯器,如圖9.1所示。
  圖9.1 在設計期指定SQL語句
  SQL語句可以分成幾行寫,但同一單詞不能分開。一般情況下,SQL屬性只能包含一條完整的SQL語句,但有些服務器允許同時執行幾條SQL語句,這種情況下,可以輸入多條SQL語句。
  如果使用Delphi 4的Client/Server版本或Enterprise版本,也可以用SQLBuilder這個實用工具來建立SQL語句。要使用SQL Builder,在TQuery構件上單擊鼠標右鍵,在彈出的菜單中選擇“SQL Builder”命令。
9.4.3 在運行期指定SQL語句
  在運行期,要指定SQL屬性有三種方式,一是直接設置SQL屬性,二是調用LoadFromFile從文件中讀取SQL語句,或者從另一個TStrings對象中獲得SQL語句。
  在直接設置SQL屬性之前,首先要調用Close函數。如果SQL屬性中本來已經有了SQL語句,還要調用Clear把原來的SQL語句清除。
  下面的代碼演示了怎樣在運行期直接設置SQL屬性:
With CustomerQuery Do
Begin
Close;
With SQL Do
Begin
Clear;
Add('SELECT * FROM Customer');
Add('WHERE Company = 'Light Diver');
End;
Open;
End;
  有時候,可能想在原來的SQL語句的基礎上修改或增加一行,這時候就不能調用Clear把原來的SQL語句清掉,例如:
  CustomerQuery.SQL[1] := 'WHERE Company = "Light Diver"';
  也可以調用LoadFromFile從文件中獲取SQL語句,這主要是因為TStrings對象支持文件操作。LoadFromFile會自動把原來的SQL語句清掉。
  下面的代碼是調用LoadFromFile的例子:
CustomerQuery.Close;
CustomerQuery.SQL.LoadFromFile('c:/orders.txt');
CustomerQuery.Open;
  還可以從另一個TStrings對象中獲取SQL語句,這就要調用TStrings的Assign函數。Assign 會自動把原來的SQL語句清空。
  下面的代碼是調用Assign的例子:
CustomerQuery.Close;
CustomerQuery.SQL.Assign(Memo1.Lines);
CustomerQuery.Open;
9.5 參 數
  要使用參數化查詢,必須在SQL語句中加入參數,例如:
INSERT INTO Country (Name, Capital, Population)
VALUES (:Name, :Capital, :Population)
  其中,Name、Capital和Population是三個參數。
  在執行上述SQL語句之前,應用程序應當調用Prepare函數通知BDE和服務器預先分配好資源,以加快查詢速度。程序示例如下:
With Query1 Do
Begin
Close;
Unprepare;
ParamByName('Name').AsString := 'China';
ParamByName('Capital').AsString := 'Beijing';
ParamByName('Population').AsInteger := '120000';
Prepare;
Open;
End;
9.5.1 在設計期提供參數
  要在設計期提供參數,單擊Params屬性邊上的省略號按鈕,彈出如圖9.2所示的編輯器。
  圖9.2 在設計期設置Params屬性
  如果SQL語句中沒有包含任何參數,圖9.2所示的編輯器就是空白的。這個編輯器的工具欄總是禁止的,這意味著只能在SQL語句中加入參數。
  選擇其中一個參數(TParam對象),就可以在對象觀察器中設置它的屬性,或者建立事件句柄。TParam的主要屬性有:
  DataType屬性用于指定參數的數據類型,它的初始值總是ftUnknown,必須設置每個參數的數據類型。
  ParamType屬性用于指定參數的使用類型,它的初始值也是ptUnknown。
  Value屬性用于給出參數的值。當然,也可以在運行期給出參數的值。
9.5.2 在運行期提供參數
  要在運行期訪問參數,有三種方式:
  一是通過ParamByName函數按名稱訪問參數。
  二是通過Params屬性按序號訪問參數。
  三是通過TParams對象的ParamValues屬性按名稱訪問參數。
  假設一條SQL語句有三個參數:
  INSERT INTO "COUNTRY.DB"
   (Name, Capital, Continent)
   VALUES (:Name, :Capital, :Continent)
  下面這行代碼通過ParamByName函數來訪問其中的Capital參數:Query1.ParamByName('Capital').AsString := Edit1.Text;
  下面這行代碼通過Params屬性來訪問其中的Name參數: 
   Query1.Params[0].AsString := Edit1.Text;
  下面這行代碼通過TParams對象的ParamValues屬性來同時訪問三個參數:
   Query1.Params.ParamValues['Country;Capital;Continent'] :=VarArrayOf([Edit1.Text, Edit2.Text, Edit3.Text]);
9.5.3 從另一個數據集獲得參數
  TQuery構件的DataSource屬性用于指定一個數據源(TDataSource構件),如果應用程序既沒有在設計期也沒有在運行期給參數賦值,它就在這個數據源中查找與參數名匹配的字段,然后用這個字段的值作為參數的值。
  假設一個數據模塊叫LinkModule,上面有一個TQuery構件叫OrdersQuery,它的SQL語句如下:
  SELECT CustNo, OrderNo, SaleDate
   FROM Orders WHERE CustNo = :CustNo
  另外,數據模塊上還有下列構件:
.一個TTable構件叫CustomersTable,它的TableName屬性設為CUSTOMER.DB。
.一個TDataSource構件叫Orderssource,它的DataSet屬性設為OrdersQuery。
.一個TDataSource構件叫CustomersSource,它的DataSet屬性設為CustomersTable。
.OrdersQuery的DataSource屬性也設為CustomersSource。
  假設應用程序有一個窗體叫LinkedQuery,窗體上有兩個TDBGrid構件,它們的DataSource屬性分別指定CustomersSource和OrdersSource。
  如果編譯和運行這個應用程序,將看到如圖9.3所示的效果:
  圖9.3 從另一個數據集獲得參數
  這里簡單解釋一下圖9.3。如果沒有對SQL語句中的:CustNo參數賦值,OrdersQuery將試圖從CustomersSource指定的數據集中查找匹配的字段。由于CustomersSource是從CUSTOMER.DB中獲取數據的,而CUSTOMER.DB中恰好有一個CustNo字段,所以,:CustNo參數的值就是CustNo字段的值。如果您在顯示CUSTOMER.DB的柵格中選擇了另一條記錄,將導致:CustNo參數的值跟著變化。
9.6 執 行 查 詢
  當指定了SQL語句并且提供了參數后,就可以執行查詢了。如果是第一次執行查詢,最好調用Prepare通知BDE或服務器做好準備,這樣能加快查詢的速度。
  既可以在設計期執行查詢,也可以在運行期執行查詢。
  要在設計期執行查詢,只要把Active屬性設為True。不過,在設計期能執行的SQL語句,僅限于SELECT語句,不能是INSERT、UPDATE或DELETE語句。
  要在運行期執行查詢,可以調用Open或ExecSQL函數,其中,Open適合于執行SELECT語句,而ExecSQL適合于執行INSERT、UPDATE或DELETE語句,后者不返回結果。
  在調用Open或ExecSQL之前,首先要調用Close。程序示例如下:
   CustomerQuery.Close;
   CustomerQuery.Open;
  如果在編程的時候無法確定是否要返回查詢結果,可以用Try...Except結構把這兩個過程都寫進去,一般Open在Try部分調用,而ExecSQL在Except部分調用,這樣,即使Open調用失敗,也能執行到ExecSQL。程序示例如下:
Try
Query2.Open;
Except
On E: Exception Do
  If not (E is ENoResultSet) then Raise;
End;
  前面多次提到,在執行查詢前最好先調用Prepare,盡管這并不是必須的。預先調用Prepare能夠改善應用程序的性能。程序示例如下:
CustomerQuery.Close;
If not (CustomerQuery.Prepared) then
CustomerQuery.Prepare;
CustomerQuery.Open;
  上述程序首先調用Close,然后檢查Prepared屬性,如果這個屬性返回True,表示已經準備好,如果這個屬性返回False,表示沒有準備好,此時就要調用Prepare。
9.7 異 構 查 詢
  所謂異構查詢,就是同時查詢幾個不同的數據庫。這些數據庫的類型可以不同。例如,可以同時查詢Oracle數據庫、Sybase數據庫和本地的dBASE表。當程序執行異構查詢的時候,BDE通過Local SQL來分析和處理這個查詢,而不是用與服務器相關的特定的SQL語法。
  建立一個異構查詢的一般步驟是這樣的:
  第一步,把一個TQuery構件放到窗體或數據模塊上,讓DatabaseName屬性空著。
  第二步,為要查詢的每一個數據庫建立一個單獨的BDE別名。
  第三步,設置SQL屬性以指定要執行的SQL語句。在SQL語句中,表的名字前要加別名和冒號,并且用雙引號括起來。字段名前要加表名和小圓點。例如:
SELECT Customer.CustNo, Orders.OrderNo
  FROM "Oracle1:CUSTOMER"
  JOIN "Sybase1:ORDERS"
  ON (Customer.CustNo = Orders.CustNo)
WHERE (Customer.CustNo = 1503)
  第四步,設置Params屬性提供參數。
  第五步,調用Prepare通知BDE或服務器做好準備,然后調用Open或ExecSQL執行查詢。如果顯式地使用TDatabase構件連接數據庫,并且設置了它的DatabaseName屬性定義了應用程序專用的別名,在SQL語句中可以用專用的別名代替BDE別名。
9.8 查 詢 結 果
  默認情況下,查詢結果是只讀的。應用程序可以用數據控件去顯示查詢結果,但用戶不能編輯數據。怎樣才能使用戶能夠編輯數據呢?
  要使用戶能夠編輯數據,必須把TQuery構件的RequestLive屬性設為True。不過,把RequestLive屬性設為True并不能保證查詢結果一定是可以修改的,因為這還取決于查詢使用的是Local SQL還是與服務器相關的SQL。
  像查詢Paradox或dBASE以及異構查詢都是使用Local SQL,而查詢遠程服務器則使用與服務器相關的SQL。即使RequestLive屬性設為True,而且查詢的是本地數據庫,但由于SELECT語句的文法不合適,BDE也將返回只讀的查詢結果。
  因此,在編輯數據之前,先要訪問CanModify屬性。只有當這個屬性返回True時,才表示查詢結果是可編輯的。

上一篇:多層數據庫開發十二:使用數據控件

下一篇:多層數據庫開發十一:TClientDataSet

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
8090成年在线看片午夜| 亚洲国产精品国自产拍av秋霞| 欧美一区二区视频97| 九九精品在线播放| 欧美在线视频在线播放完整版免费观看| 在线日韩精品视频| 久久久久久噜噜噜久久久精品| 欧美劲爆第一页| 1769国产精品| 97精品伊人久久久大香线蕉| 欧美福利视频网站| 日韩av成人在线| 久久精品亚洲一区| 亚洲成人久久一区| 日韩高清av在线| 亚洲亚裔videos黑人hd| 欧美日韩aaaa| 欧美裸身视频免费观看| 欧美在线欧美在线| 欧美有码在线观看| 亚洲精品久久视频| 欧美精品videossex性护士| 久久久久久九九九| 欧美性xxxxxx| 欧美性理论片在线观看片免费| 欧洲午夜精品久久久| 国产精品一区二区女厕厕| 久久夜精品香蕉| 欧美在线亚洲在线| 国产日韩欧美在线观看| 成人春色激情网| 久久精品美女视频网站| 国产aⅴ夜夜欢一区二区三区| 亚洲新中文字幕| 一区二区中文字幕| 欧美精品情趣视频| 欧美综合在线第二页| 亚洲老板91色精品久久| 亚洲最新在线视频| 欧美日韩美女在线观看| 国产精品劲爆视频| 欧美大片va欧美在线播放| 国产精品一区专区欧美日韩| 日韩a**站在线观看| 国产精品∨欧美精品v日韩精品| 色噜噜狠狠色综合网图区| 成人激情黄色网| 中文字幕av一区中文字幕天堂| 亚洲第一综合天堂另类专| 欧美性20hd另类| 久久久久久久久电影| 亚洲第一页自拍| 日韩av中文在线| 欧美亚洲在线视频| 日韩成人av网址| 黑人巨大精品欧美一区二区免费| 亚洲激情久久久| 欧美激情一级精品国产| 8x海外华人永久免费日韩内陆视频| 欧美亚洲成人免费| 丰满岳妇乱一区二区三区| 日韩欧美在线视频日韩欧美在线视频| 欧美华人在线视频| 国产精品视频xxxx| 国产精品久久色| 久久成人这里只有精品| 国产欧美日韩中文| 亚洲人成网在线播放| 97久久久久久| 亚洲欧美国内爽妇网| 亚洲欧美综合精品久久成人| 久久精品国产免费观看| 久久青草精品视频免费观看| 亚洲成人av中文字幕| 色综合五月天导航| 亚洲日韩欧美视频一区| 亚洲人成在线电影| 2018日韩中文字幕| 欧美极品少妇xxxxx| 精品国产依人香蕉在线精品| 亚洲香蕉av在线一区二区三区| 成人欧美在线视频| 欧美中文字幕在线视频| 国产剧情日韩欧美| 久久91亚洲精品中文字幕奶水| 欧美人交a欧美精品| 孩xxxx性bbbb欧美| 91精品国产精品| 97在线视频免费观看| 日韩精品福利在线| 国产精品视频公开费视频| 午夜免费在线观看精品视频| 欧美另类第一页| 欧美电影第一页| 国产精品欧美一区二区| 亚洲精品成人久久| 欧美电影电视剧在线观看| 日韩激情av在线免费观看| 91av视频导航| 亚洲天堂av综合网| 色樱桃影院亚洲精品影院| 亚洲激情视频网| 日本不卡视频在线播放| 久久亚洲国产精品成人av秋霞| 久久99精品久久久久久青青91| 91久久国产综合久久91精品网站| 国产精品亚洲第一区| 欧美在线免费观看| 51精品国产黑色丝袜高跟鞋| 97在线看福利| 日韩欧美视频一区二区三区| 精品亚洲精品福利线在观看| 色婷婷**av毛片一区| 欧美激情精品在线| 91亚洲国产成人精品性色| 亚洲国产毛片完整版| 国语自产精品视频在线看一大j8| 久久亚洲国产精品成人av秋霞| 日韩欧美国产骚| 欧美亚洲日本黄色| 在线观看国产精品91| 亚洲激情自拍图| 欧美一乱一性一交一视频| 国产精品专区一| 亚洲电影免费观看高清完整版在线观看| 日韩在线视频免费观看高清中文| 欧美成人亚洲成人| 欧美成人免费在线视频| 97视频网站入口| 亚洲午夜国产成人av电影男同| 亚洲精品久久久久| 97婷婷涩涩精品一区| 欧美性videos高清精品| 亚洲人成网站免费播放| 欧美性猛交xxxx偷拍洗澡| 国产精品视频网址| 久久人人看视频| 久久久久久欧美| 国产精品第一视频| 亚洲第一av在线| 欧美激情精品久久久久久大尺度| 国产精品视频一区二区三区四| 国产精品久久久久久久久免费| 欧美成人精品三级在线观看| 成人有码在线播放| 久久久久久国产精品三级玉女聊斋| 国产中文字幕亚洲| 久热精品视频在线免费观看| 一区二区三区无码高清视频| 国内揄拍国内精品少妇国语| 美女精品视频一区| 91精品国产精品| 国产一区二区三区三区在线观看| 国产精品视频久| 国模精品一区二区三区色天香| 亚洲综合中文字幕在线| 91老司机精品视频| 精品五月天久久| 91精品国产乱码久久久久久蜜臀| 国产欧美日韩中文字幕在线| 日韩经典中文字幕在线观看| 午夜精品久久久久久99热软件| 91精品国产自产91精品| 综合136福利视频在线|