Delphi是一個可視化的編程工具,ADO編程也是這樣,所以話不多言,直接通過代碼、截圖和語言來說明。
我的數據庫是Oracle,為了測試,先建一個表:create table practice(uno varchar(8), uname varchar(20)); 這個表比較簡單,只有兩個字段。
我的Oracle數據庫是安裝在虛擬機上的(操作系統是Redhat),所以需要先在服務器上配置好,另外需要在Windows上進行相關的配置(監聽程序配置和本地網絡服務名配置)。否則后面就沒有辦法配置數據源……來連接數據庫。具體怎么進行配置請自己上網搜索查詢。
然后我們來做一個簡單的增刪改查的小工具。
1.新建一個項目,上面放好需要控件
如下圖,其中最為重要的一個控件是用紅框框起來的控件:TADOConnection
注意需要引入DB、ADODB這兩個單元。
2.雙擊TADOConnection控件進行配置
雙擊TADOConnection打開
點擊Build..按鈕,先選擇數據庫驅動,我選擇的是最后一個
像我使用的是Oracle數據庫,所以需要選擇Oracle的數據庫驅動,這里面提供的Oracle數據庫驅動有兩種(Oracle自己的驅動還有微軟提供的Oracle驅動),如下圖用紅框標記的
點擊下一步,配置數據源,用戶名密碼等信息,選擇允許保存密碼,點擊確定
然后點擊OK即可進行 下一步的編程工作
3.然后實增刪改查的功能
首先是在響應窗體創建事件的函數中打開TADOConnection對象con1
1
2
3
4
|
procedure
TForm1
.
FormCreate(Sender: TObject);
begin
con1
.
Open;
end
;
|
這里不需要調用con1.Create,因為通過將控件直接拖拽到窗體上的方式,會在窗體創建的時候也創建這些控件,如果這里在Create就會重復創建,重復創建就會出錯。
接着是實現 “增” 的功能雙擊設計面板上的按鈕,編寫按鈕響應OnClick的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
|
procedure
TForm1
.
btn1Click(Sender: TObject);
var
adoQuery: TADOQuery;
count:
Integer
;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoQuery
.
SQL
.
Text :=
'INSERT INTO practice VALUES('
''
+ edt1
.
Text +
''
', '
''
+ edt2
.
Text +
''
')'
;
count:= adoQuery
.
ExecSQL;
if
(count>
0
)
then
ShowMessage(
'成功插入'
+IntToStr(count) +
' 條數據'
);
adoQuery
.
Free;
end
;
|
注意其中的代碼的一些細節。
將adoQuery的Connection屬性設置為con1。
拼接SQL的時候,注意兩個單引號 ''的使用規范。
對於往數據庫中寫數據的SQL,需要使用ExecSQL方法,insert、delete、update這樣的寫數據庫的方法,需要調用ExecSQL方法,ExecSQL方法的返回值是這條SQL影響了數據庫中的幾條記錄(比如:插入了幾條記錄、刪除了幾條記錄、修改了幾條記錄),所以這個方法中會用到ExecSQL的返回值。
最后不要忘了釋放adoQuery對象。保證不會出現內存泄露,因為如果不釋放,那么每次點擊按鈕就會創建一個adoQuery對象。不過這樣使用局部變量也不是很好,可以使用TADDOQuery創建一個全局變量,在程序打開的時候創建好,做好Connection屬性的賦值,然后使用,最后使用完成在程序關閉的時候再釋放,這樣就可以防止每次點擊按鈕都要創建,不過使用TADOQuery全局變量也要有一些規范,參見下面的總結說明!
補充說明TADOQuery
要想執行SQL需要創建TADOQuery對象。我們可以將AdoQuery作為一個局部變量,然后這個小demo中需要實現的增刪改查每個都創建自己的TADOQuery局部變量,執行完之后再Free,當然也可以創建全局變量,然后每個操作都使用這個全局變量。
但是如果使用全局變量的話,特別需要注意一點。在原來的使用TADOQuery局部變量的時候,每個操作之前先創建一個TADOQuery對象,然后將其Connection屬性賦值為那個TADOConnection的變量,然后給SQL.Text賦值,然后就可以Open或者ExecSQL執行了,最后在程序結束的時候在進行Free即可。
但是如果使用TADOQuery全局變量的話,首先是Create好TADOQuery,然后給它的Connection賦好值,然后每個操作的時候,直接將其SQL.Text賦值,然后執行就好了。不過在這個過程中必須注意在給SQL.Text賦值之前需要執行TADOQuery的Close方法,然后再SQL.Clear,然后再賦值SQL,然后再執行。
1
2
3
4
5
6
|
begin
adoquery
.
close;
adoquery
.
SQL
.
clear;
adoquery
.
SQL
.
add(
'...'
);
adoquery
.
open;
//如果是寫操作的話就是adoquery.ExecSQL;
end
;
|
這是一個經典的語句,在每次查詢之前先把上次刪除給關了。 如果不關,第一次查詢是沒問題的,可如果adoqury1再用一次的話,就會有可能和上次發生沖突。 程序的不確定性很強,所以這樣做是有必要的,防止出現意想不到的問題。
Close還是需要。還有一點就是節約內存,用過就關,不然會一直呆在內存里面!!所以不管是使用adoquery.SQL.Text 還是adoquery.SQL.Add(),如果是全局變量的話,還是要使用Close方法。
Clear看情況決定要不要。不過如果是直接給adoquery.SQL.Text賦值的話,可以不用執行adoquery.SQL.Clear因為新賦的值將會覆蓋原來的值。但是如果是使用adoquery.SQL.Add()的話,是在原來的SQL基礎上追加,所以可能需要Clear原來的SQL,再添加新的SQL,保證可以不和上次沖突!
再補充說明adoquery.SQL.Add和adoquery.SQL.Text的區別
1
2
3
4
5
6
|
//adoquery1.sql.add相當於添加一個值比如說
adoquery1
.
sql
.
text:=
'a'
;
adoquery1
.
sql
.
add(
'b'
);
//那么就相當於直接
adoquery1
.
sql
.
text=
'ab'
;
|
adoquery1.sql.text 就是說寫一行完整的查詢語句放在SQl的查詢里。當在delphi中SQL語句太長,我們可以把adoquery1.sql.text 分開由多個adoquery1.sql.add()來分段寫。
adoquery1.sql.add()主要起追加的作用。
接着實現 “查” 的功能,同樣編寫按鈕響應OnClick的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
procedure
TForm1
.
btn2Click(Sender: TObject);
var
adoQuery: TADOQuery;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoQuery
.
SQL
.
Text :=
'SELECT * FROM practice WHERE uno = '
''
+ edt3
.
Text +
''
''
;
adoQuery
.
Open;
adoQuery
.
First;
while
not
adoQuery
.
Eof
do
begin
ShowMessage(adoQuery
.
fieldByName(
'uno'
).AsString +
': '
+ adoQuery
.
fieldByName(
'uname'
).AsString);
adoQuery
.
Next;
end
;
adoQuery
.
Free;
end
;
|
執行Select的SQL,需要使用Open,而不是ExecSQL方法。
通過判斷Eof來進行循環展示搜索到的數據庫中的符合條件的記錄。判斷是否Eof,注意Eof為True並不是指向了最后一條記錄的時候,而是指向了最后一條記錄之后,再Next時Eof才是True。
First是定位到所有搜索到的記錄的第一條。Next是指向下一條。
根據字段名稱獲取每條記錄的對應信息,注意這里面使用FieldByName獲取字段對應的值的方法。因為前面是使用的select * from,所以可以既獲得'uno',有可以獲得'uname',假如用select uname from 的話,就只能使用fieldByName獲得'uname',不能獲得'uno',所以使用fieldByName時候需要注意select語句搜索了哪幾項。
接下來講解刪除功能的代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
procedure
TForm1
.
btn3Click(Sender: TObject);
var
adoQuery: TADOQuery;
count:
Integer
;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoQuery
.
SQL
.
Text :=
'DELETE FROM practice WHERE uno = '
''
+ edt4
.
Text +
''
''
;
count:= adoQuery
.
ExecSQL;
if
count>
0
then
ShowMessage(
'刪除'
+ IntToStr(count) +
' 條數據'
)
else
ShowMessage(
'沒有刪除數據'
);
adoQuery
.
Free;
end
;
|
最后是改數據庫數據的功能代碼
1
2
3
4
5
6
7
8
9
10
11
12
|
procedure
TForm1
.
btn4Click(Sender: TObject);
var
adoquery: TADOQuery;
count:
Integer
;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoquery
.
SQL
.
Text:=
'UPDATE practice SET uname = '
''
+ edt6
.
Text +
''
'WHERE uno = '
''
+ edt5
.
Text +
''
''
;
count:= adoquery
.
ExecSQL;
ShowMessage(
'修改了'
+ IntToStr(count) +
' 條記錄'
);
adoQuery
.
Free;
end
;
|
最后的代碼是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
unit
Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB;
type
TForm1 =
class
(TForm)
con1: TADOConnection;
edt1: TEdit;
lbl1: TLabel;
edt2: TEdit;
lbl2: TLabel;
btn1: TButton;
edt3: TEdit;
lbl3: TLabel;
btn2: TButton;
edt4: TEdit;
lbl4: TLabel;
btn3: TButton;
edt5: TEdit;
lbl5: TLabel;
edt6: TEdit;
lbl6: TLabel;
btn4: TButton;
procedure
FormCreate(Sender: TObject);
procedure
btn1Click(Sender: TObject);
procedure
btn2Click(Sender: TObject);
procedure
btn3Click(Sender: TObject);
procedure
btn4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end
;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure
TForm1
.
FormCreate(Sender: TObject);
begin
con1
.
Open;
end
;
procedure
TForm1
.
btn1Click(Sender: TObject);
var
adoQuery: TADOQuery;
count:
Integer
;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoQuery
.
SQL
.
Text :=
'INSERT INTO practice VALUES('
''
+ edt1
.
Text +
''
', '
''
+ edt2
.
Text +
''
')'
;
count:= adoQuery
.
ExecSQL;
if
(count>
0
)
then
ShowMessage(
'成功插入'
+IntToStr(count) +
' 條數據'
);
adoQuery
.
Free;
end
;
procedure
TForm1
.
btn2Click(Sender: TObject);
var
adoQuery: TADOQuery;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoQuery
.
SQL
.
Text :=
'SELECT * FROM practice WHERE uno = '
''
+ edt3
.
Text +
''
''
;
adoQuery
.
Open;
adoQuery
.
First;
while
not
adoQuery
.
Eof
do
begin
ShowMessage(adoQuery
.
fieldByName(
'uno'
).AsString +
': '
+ adoQuery
.
fieldByName(
'uname'
).AsString);
adoQuery
.
Next;
end
;
adoQuery
.
Free;
end
;
procedure
TForm1
.
btn3Click(Sender: TObject);
var
adoQuery: TADOQuery;
count:
Integer
;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoQuery
.
SQL
.
Text :=
'DELETE FROM practice WHERE uno = '
''
+ edt4
.
Text +
''
''
;
count:= adoQuery
.
ExecSQL;
if
count>
0
then
ShowMessage(
'刪除'
+ IntToStr(count) +
' 條數據'
)
else
ShowMessage(
'沒有刪除數據'
);
adoQuery
.
Free;
end
;
procedure
TForm1
.
btn4Click(Sender: TObject);
var
adoquery: TADOQuery;
count:
Integer
;
begin
adoQuery := TADOQuery
.
Create(
nil
);
adoQuery
.
Connection := con1;
adoquery
.
SQL
.
Text:=
'UPDATE practice SET uname = '
''
+ edt6
.
Text +
''
'WHERE uno = '
''
+ edt5
.
Text +
''
''
;
count:= adoquery
.
ExecSQL;
ShowMessage(
'修改了'
+ IntToStr(count) +
' 條記錄'
);
adoQuery
.
Free;
end
;
end
.
|