csdl3_chuong3
CHƯƠNG 3: VISUAL FOXPRO VỚI SQL SERVER
Visual FoxPro cung cấp hai cơ chế làm việc với dữ liệu dạng client/server là
view từ xa và cơ chế SQL pass through.
1. Làm việc với view từ xa
Một view từ xa là một phát biểu SELECT của SQL được lưu trữ trong cơ sở dữ
liệu của Visual FoxPro. View từ xa sử dụng cơ chế ODBC (Open DataBase
Connectivity) để kết nối dữ liệu.
1.1 Kết nối
Trước khi tạo một view từ xa thì phải xác định view đó sẽ kết nối vào cơ sở dữ
liệu như thế nào. Có nhiều cách để làm việc này, nhưng tất cả đều sử dụng ODBC. Vì
thế cả hai trình điều khiển ODBC ở server và client đều phải được cài đặt. Đối với
SQL server, việc cài đặt được thự hiện khi cài Visual Studio hoặc SQL Server.
Để có thể kết nối đến cơ sở dữ liệu đầu tiên chúng ta cần phải tạo một DSN.
Có ba loại DSN: Người dùng, hệ thống và file. Một DSN của người dùng chỉ có thể
được sử dụng bởi một người chỉ định, trong khi DSN hệ thống có thể được sử dụng
bởi bất kì người dùng nào trên máy. DSN người dùng và DSN hệ thống được lưu trữ
trong registry của máy trạm, trong khi file DSN được lưu trữ trong các file văn bản và
có thể tìm kiếm ở bất cứ nơi nào.
Lệnh CREATE CONNECTION
Đặt tên cho kết nối tới cơ sở dữ liệu từ xa và lưu trữ trong cơ sở dữ liệu hiện
thời. Dạng lệnh:
CREATE CONNECTION [ConnectionName | ?]
[DATASOURCE cDataSourceName]
[USERID cUserID] [PASSWORD cPassWord]
[DATABASE cDatabaseName]
| CONNSTRING cConnectionString]
Trong đó:
ConnectionName: Tên của kết nối sẽ được tạo.
DATASOURCE cDataSourceName: Chỉ định tên nguồn dữ liệu trong ODBC
cho kết nối
USERID cUserID: Chỉ định tên truy cập dữ liệu được lưu trong dữ liệu ODBC
PASSWORD cPassWord: Chỉ định mật khNu truy cập dữ liệu được lưu trong
dữ liệu ODBC
DATABASE cDatabaseName: Tên cơ sở dữ liệu trên Server
CONNSTRING cConnectionString: Chỉ định một chuỗi kết nối cho các nguồn
dữ liệu ODBC. Chuỗi kết nối có thể được sử dụng thay thế việc khai báo rõ ràng trong
dữ liệu ODBC.
Ví dụ 1:
CLOSE DATABASES
OPEN DATABASE NorthWind
CREATE CONNECTION Myconn DATASOURCE "NorthWind"
CLEAR
DISPLAY CONNECTIONS
DELETE CONNECTIONS Myconn
Ví dụ 2:
CLOSE DATABASES
OPEN DATABASE NorthWind
St=[DSN=NorthWind; WSID=DRAGON;DATABASE=Northwind]
CREATE CONNECTIONS Myconn CONNSTRING (st)
1.2 Tạo view từ xa
Lệnh CREATE SQL VIEW
CREATE [SQL] VIEW [ViewName] REMOTE
CONNECTION ConnectionName [SHARE] | CONNECTION DataSourceName
AS SQLSELECTStatement
Trong đó:
ViewName: Tên của view sẽ được tạo bởi lệnh
ConnectionName: Chỉ định tên của kết nối đã lập
DataSourceName: Tên của data source đã tồn tại để kết nối tới cơ sở dữ liệu.
SQLSELECTStatement: Câu lệnh SELECT của SQL
SHARE: Chỉ định kết nối được dùng chung cho các view từ xa.
Ví dụ:
CLOSE DATABASES
OPEN DATABASE Northwind
CREATE SQL VIEW MyView REMOTE CONNECTION Myconn SHARE;
AS SELECT * FROM Customers WHERE Country=’Mexico’
DBSETPROP(‘MyView’,’View’,’ShareConnection’, .T.)
USE MyView AGAIN IN 0
SELECT MyView
BROWSE LAST
USE IN MyView
DELETE VIEW MyView
Với ví dụ trên view này chỉ áp dụng cho các khách hàng ở Mexico mà không
áp dụng được với các khách hàng khác. Visual FoxPro cho phép tạo các view có
thông số, và các thông số này được đặt sau dấu chấm hỏi (?). Một thông số của view
là một biến nhớ, chúng sẽ được truyền vào view khi thực thi view đó.
Ví dụ tạo view có thông số cCountry như sau:
CLOSE DATABASES
OPEN DATABASE NorthWind
CREATE SQL VIEW MyView REMOTE CONNECTION Myconn SHARE;
AS SELECT * FROM Customers WHERE Country LIKE ?cCountry
cCountry=’U%’
USE MyView AGAIN IN 0
SELECT MyView
BROWSE LAST
USE IN MyView
DELETE VIEW myview
Nếu cCountry tồn tại khi view được mở hoặc sử dụng hàm REQUERY() hoặc
hàm REFRESH(), giá trị của biến sẽ được cung cấp cho mệnh đề where. Trong trường
hợp biến cCountry không tồn tại NSD sẽ được nhắc nhở cung cấp giá trị truyền cho
Nếu dùng hàm DBSETPROP():
Để chỉ định một cột làm khóa chính, dùng lệnh:
DBSetProp(Column_Name,"Field","KeyField",.T.)
Ví dụ:
DBSetProp(“MyView.customerid","Field","KeyField",.T.)
Để chỉ định một cột có thể cập nhật được, dùng lệnh:
DBSetProp(Column_name,"Field","Updatable",.T.)
Ví dụ
DBSetProp(“MyView.customerid","Field","Updatable",.T.)
Để cho view có thể cập nhật được, phải chỉ định
DBSetProp(View_Name,"View","SendUpdates",.T.)
Ví dụ
DBSetProp(“MyView”,"View","SendUpdates",.T.)
Chỉ định thuộc tính WhereType cho view, dùng lệnh
DBSetProp(View_Name,"View","WhereType", n)
Trong đó:
· n=1 (DB_KEY – Key field only): Xung đột sẽ xảy ra khi thay
đổi trên khóa chính. Khi đó, thay đổi trên khóa chính sẽ bị bỏ
qua.
· n=2 (DB_KEYANDUPDATETABLE – Key and updatable
fields): xung đột sẽ xảy ra khi thay đổi trên khóa chính hoặc các
trường (cột) cập nhật. Nếu có hai NSD cùng thay đổi trên các cột
cập nhật thì sẽ phát sinh lỗi.
· n=3 (DB_KEYANDMODIFIED – key and modified fields):
xung đột sẽ xảy ra khi thay đổi trên khóa chính hoặc các trường
(cột) cập nhật. Nếu có hai NSD cùng thay đổi trên một cột cập
nhật thì sẽ phát sinh lỗi.
· n=4 (DB_KEYANDTIMESTAMP – key and timestamp): xung
đột sẽ xảy ra khi thay đổi trên khóa chính hay thay đổi trên các
cột kiểu timestamp.
Ví dụ
DBSetProp(“MyView”,"View","WhereType",3)
Thiết lập thuộc tính UpdateType, dùng lệnh
DBSetProp(View_name,"View","UpdateType", n)
Trong đó
· n=1 (DB_UPDATE – SQL Update): Cập nhật dữ liệu mới
thay cho dữ liệu cũ.
· n=2 (DB_DELETEINSERT - SQL DELETE then INSERT):
Xóa dữ liệu cũ và chèn dữ liệu mới.
Ví dụ:
DBSetProp(“MyView”,"View","UpdateType", 1)
1.4 Bộ đệm cho view
Khi làm việc với cơ sở dữ liệu client/server, chúng ta không thể làm việc trực
tiếp được với các bảng mà làm việc trong các vùng đệm của các view. Với Visual
FoxPro có hai loại bộ đệm cho view: bộ đệm dòng và bộ đệm bảng. Bộ đệm dòng
hoàn tất các thay đổi mỗi lần trên một dòng còn bộ đệm bảng hoàn tất mỗi lần cho
nhiều dòng. Khi mở một view, bộ đệm dòng và bảng không được hỗ trợ. Để thay đổi
loại bộ đệm cần thiết lập thuộc tính cho cursor bằng hàm CURSORSETPROP(), dạng:
CURSORSETPROP(“Buffering”, nExpression, [,cTableAlias | nWorkArea])
Trong đó:
· nExpression=1: Tắt bộ đệm cho các dòng và các view.
· nExpression=2: Đặt bộ đệm dòng ở chế độ pessimistic
· nExpression=3: Đặt bộ đệm dòng ở chế độ optimistic
· nExpression=4: Đặt bộ đệm bảng ở chế độ pessimistic
· nExpression=5: Đặt bộ đệm bảng ở chế độ optimistic
Khi nExpression>1 thì cần chỉ định SET MULTILOCKS là ON.
Ví dụ:
CURSORSETPROP(“Buffering”, 5, “MyView”)
Để quản lí trạng thái của các bộ đệm khi view đặt trong bộ đệm bảng, chúng ta
sử dụng hàm TABLEUPDATE() để gửi các thay đổi về server, TABLEREVERT() để
khôi phục trạng thái ban đầu của dữ liệu.
Hàm TABLEUPDATE(): Gửi các thay đổi về server
TABLEUPDATE( [nRows [, lForce]] [, cTableAlias | nWorkArea] )
Trong đó:
nRows: Chỉ định việc thay đổi trên bảng hay cursor đã hoàn tất
· nRows =0 (Tương đương với giá trị .F.): Hoàn tất sự thay đổi ở tại dòng
hiện tại và gửi các thay đổi này về server (ngầm định).
· nRows =1 (Tương đương với giá trị .T.): Hoàn tất sự thay đổi ở tất cả
các dòng trên bảng hay cursor và gửi các thay đổi này về server.
· nRows =2: Hoàn tất sự thay đổi ở tất cả các dòng trên bảng hay cursor
và gửi các thay đổi này về server. Tuy nhiên, nếu xuất hiện xung đột khi
cập nhật (tại một dòng nào đó) thì Visual FoxPro vẫn tiếp tục cập nhật
cho các dòng còn lại của bảng hay cursor.
lForce: Chỉ định xem Visual FoxPro có ghi đè các thay đổi trên bảng hay
cursor bởi NSD khác hay không
· lForce = .F. : Hoàn tất các thay đổi trên bảng hay cursor, bắt đầu từ
dòng đầu tiên cho đến dòng cuối cùng của bản hay cursor (Ngầm định).
· lForce = .T. : Ghi đè các thay đổi trên bảng hay cursor bởi NSD khác
trên mạng. Khi đó WhereType phải sử dụng là only key fields.
Hàm này trả về .T. khi các thay đổi hoàn tất thành công, và trả về .F. nếu xuất
hiện lỗi khi hoàn tất các thay đổi trên bảng hay cursor.
Ví dụ:
CLOSE DATABASES
OPEN DATABASE NorthWind
CREATE SQL VIEW MyView REMOTE CONNECTION Myconn SHARE;
AS SELECT * FROM Customers WHERE Country like ?cCountry
DBSETPROP(“MyView”,”View”,”ShareConnection”, .T.)
**Update on database server
** DBSETPROP("Myview","VIEW","SendUpdates",.T.)
cCountry=’M%’
USE MyView
SET MULTILOCKS ON && Must turn on for table buffering.
= CURSORSETPROP('Buffering', 5, 'MyView' ) && Enable table buffering.
CLEAR
GO TOP
? 'Original City value: '
?? City && Displays current City value (México D.F.
).
REPLACE City WITH 'New City'
? 'New City value: '
?? City && Displays new Cityvalue (New City).
= TABLEUPDATE(.T.) && Commits changes.
**Refreshing MyView
**=REQUERY()
? 'Updated City value: '
?? City && Displays current City value (New City).
USE IN MyView
DELETE VIEW MyView
Hàm TABLEREVERT(): Hủy bỏ các thay đổi ở vùng đệm dòng hay bảng
TABLEREVERT( [lAllRows [, cTableAlias | nWorkArea] ] )
Trong đó:
lAllRows: quyết định có hủy bỏ các thay đổi trên bảng hay cursor hay không?
· lAllRows=.F. : Chỉ những thay đổi trên dòng hiện tại của bảng hay
cursor bị hủy bỏ (ngầm định)
· lAllRows=.T. : Tất cả các thay đổi trên bảng hay cursor đều bị hủy bỏ
Hàm này trả về số các dòng của bảng hay cursor bị hủy bỏ.
Ví dụ:
CLOSE DATABASES
OPEN DATABASE NorthWind
CREATE SQL VIEW MyView REMOTE CONNECTION Myconn SHARE;
AS SELECT * FROM Customers WHERE Country like ?cCountry
DBSETPROP(“MyView”,”View”,”ShareConnection”, .T.)
*Update on database server
DBSETPROP("Myview","VIEW","SendUpdates",.T.)
cCountry=’M%’
USE MyView
SET MULTILOCKS ON && Must turn on for table buffering.
= CURSORSETPROP('Buffering', 5, 'MyView' ) && Enable table buffering.
CLEAR
Go top
?’original city valie:’
??city %% díplays current city value(mexico DF)
REPLACE City WITH 'New City' && Changes field contents
? 'New City value: '
?? City && Displays new Cityvalue (New City).
= TABLEREVERT(.T.) && Discard all table changes.
=REQUERY()
? 'Reverted City value: '
?? City && Displays reverted City value (México D.F.).
USE IN MyView
DELETE VIEW MyView
1.5 Các kiểu dữ liệu tương thích
Giữa SQL Server và Visual FoxPro không có kiểu dữ liệu tưng xứng. Ví như,
Visual FoxPro hỗ trợ hai kiểu dữ liệu date và datetime, còn SQL Server thì không hỗ
trợ kiểu dữ liệu date nhưng lại có hai kiểu datetime và smalldatetime.
Khi tạo một view từ xa, Visual FoxPro sẽ tự động chuyển các kiểu dữ liệu của
SQL Server sang các kiểu dữ liệu tương ứng như bảng dưới.
Chúng ta cũng có thể sử dụng hàm DBSETPROP() để chuyển kiểu dữ liệu cho
bất kì trường (cột) nào trong view. Ví dụ, để ép kiểu từ datetime thành date trong
Visual FoxPro cho cột Birthday của view vEmployees ta dùng lệnh:
DBSETPROP(“vEmployees.BirthDay”,”Field”, “DataType”,”D”)
2. SQL Pass Through
View từ xa là cách dễ nhất để truy cập dữ liệu từ xa. Tuy nhiên, do dễ dàng sử
dụng nên nó thiếu tính mềm dẻo. Visual FoxPro có một cơ chế mạnh khác để quản lí
dữ liệu từ xa gọi là SQL Pass Through. SQL Pass Through có tất cả các tính năng mà
view từ xa cung cấp. Ngoài ra, SQL Pass Through còn có thể:
Thực thi các truy vấn khác với phát biểu SELECT
Lấy về nhiều tập kết quả trong một lời gọi.
Thực thi các thủ tục thường trú.
Tuy nhiên, SQL Pass Through
Không có giao diện NSD
Các kết nối phải quản lí thủ công
Các tập kết quả được mặc định là chỉ đọc, nên muồn cập nhật thì phải
cấu hình lại
2.1 Kết nối
Với kĩ thuật SQL Pass Through (SPT), chúng ta phải tạo và quản lí kết nối thủ
công. Để thiết lập các kết nối tới máy chủ từ xa chúng ta sử dụng một trong hai hàm
SQLConnect() và SQLStringConnect().
Hàm SQLConnect()
SQLCONNECT([cConnectionName | cDataSourceName [, cUserID [, cPassword ]][, lShared]])
Trong đó:
cConnectionName: chỉ định tên của kết nối được tạo bởi lệnh CREATE
CONNECTION
cDataSourceName: Tên của DSN có trong ODBC Administrator
cUserID: Tên của NSD dùng để đăng nhập vào server
cPassword : Mật khNu để đăng nhập vào server
lShared: Có tạo kết nối chia xẻ hay không.
Hàm này trả về một giá trị số và trả về số dương nếu kết nối thành công, trả về
-1 nếu thất bại.
Ví dụ:
LOCAL hConn
hConn=SQLConnect(“NorthWind”) && Northwind is DSN name
** Tên login: THTCKT, Mật khNu: 123456
hConn=SQLConnect("NorthWind","THTCKT","123456",.T.)
Ví dụ
CLOSE DATABASES
OPEN DATABASE NorthWind
** Kết nối MyConn có trong cơ sở dữ liệu NorthWind
hConn=SQLConnect("MyConn")
IF hConn < 0
= MESSAGEBOX('Cannot make connection', 16, 'SQL Connect Error')
ELSE && successful connection
= MESSAGEBOX('Connection made', 48, 'SQL Connect Message')
= SQLDISCONNECT(hConn)
ENDIF
Hàm SQLStringConnect()
SQLSTRINGCONNECT([lShared] | [cConnectString [, lSharable]])
Trong đó:
lShared: Có tạo kết nối chia xẻ hay không.
cConnectString: Chỉ định xâu kết nối đầy đủ để kết nối vào máy chủ. Xâu kết
nối bao gồm các tùy chọn được phân cách nhau bởi dấu chám phảy (;) để biểu diễn
nguồn dữ liệu và các thiết lập kết nối. Các tùy chọn thường sử dụng được cho ở bảng
sau:
lSharable: Chỉ định xâu kết nối cConnectString là chia xẻ hay không.
Hàm này trả về một giá trị số và trả về số dương nếu kết nối thành công, trả về
-1 nếu thất bại.
Ví dụ:
LOCAL hConn
stConn= “Driver=SQL Server;” ;
+ "SERVER=DRAGON\SQLEXPRESS;" ;
+ "UID=THTCKT;" ;
+ "PWD=123456;" ;
+ "DATABASE=NORTHWIND;" ;
+ "WSID=DRAGON"
hConn=SQLSTRINGCONNECT(stConn)
Ví dụ:
LOCAL hConn
stConn= “DSN=NorthWind;” ;
+ "DATABASE=NORTHWIND;" ;
+ "Trusted_connection=Yes"
hConn=SQLSTRINGCONNECT(stConn)
IF hConn < 0
= MESSAGEBOX('Cannot make connection', 16, 'SQL Connect Error')
ELSE && successful connection
= MESSAGEBOX('Connection made', 48, 'SQL Connect Message')
= SQLDISCONNECT(hConn)
ENDIF
Hàm SQLDisconnect()
nReturnValue = SQLDisconnect( nConnectionHandle )
2.2 Đệ trình các truy vấn
Đa phần các tương tác với server từ xa trong Visual FoxPro thông qua hàm
SQLExec(). Nhiệm vụ chính của hàm SQLExec() là gửi một câu truy vấn tới server và
server sẽ trả kết quả về cho Visual FoxPro.
nSuccess = SQLEXEC(nStatementHandle[, cSQLCommand [, cCursorName]])
Trong đó
* In synchronous mode
nHandle = SQLConnect("Northwind")
IF nHandle > 0
IF SQLExec(nHandle, "Select * FROM Customers") = 1
BROWSE
ELSE
WAIT WINDOW "Trouble at the pass"
ENDIF
ELSE
WAIT WINDOW "Can't connect"
ENDIF
* Set up a parameterized SPT command
* Use the same connection as above
cCountry = ""
IF SQLPrepare(nHandle, ;
"SELECT * FROM Customers WHERE Country = ?cCountry") = 1
cCountry = "UK"
IF SQLExec(nHandle) = 1
* Got all UK Customers
BROWSE TITLE "Customers in the UK"
ENDIF
cCountry = "USA"
IF SQLExec(nHandle) = 1
* Got all US Customers
BROWSE TITLE "Customers in the USA"
ENDIF
ENDIF
Truy vấn trả về một tập kết quả
LOCAL hConn
stConn= “DSN=NorthWind;” ;
+ "DATABASE=NORTHWIND;" ;
+ "Trusted_connection=Yes"
hConn=SQLSTRINGCONNECT(stConn)
IF hConn < 0
= MESSAGEBOX('Cannot make connection', 16, 'SQL Connect Error')
ELSE && successful connection
lnResult=SQLExec(hConn,[SELECT * FROM Customers ];
+[ WHERE City LIKE ’M%’], [Customers])
IF lnResult>0
SELECT Customers
BROWSE
USE IN Customers
ELSE
=MESSAGEBOX([An error occurred],16,[Note])
ENDIF
= SQLDISCONNECT(hConn)
ENDIF
Truy vấn trả về nhiều tập kết quả
LOCAL hConn
stConn= “Driver=SQL Server;” ;
+ "SERVER=DRAGON\SQLEXPRESS;" ;
+ "UID=THTCKT;" ;
+ "PWD=123456;" ;
+ "DATABASE=NORTHWIND;" ;
+ "WSID=DRAGON"
hConn=SQLSTRINGCONNECT(stConn)
IF hConn < 0
= MESSAGEBOX('Cannot make connection', 16, 'SQL Connect Error')
ELSE && successful connection
lnResult=SQLExec(hConn,[SELECT * FROM Customers ;] ;
+[ SELECT * FROM Employees])
IF lnResult>0
SELECT SQLResult
BROWSE TITLE "Customers "
USE IN SQLResult
SELECT SQLResult1
BROWSE TITLE "Employees "
USE IN SQLResult1
ELSE
=MESSAGEBOX([An error occurred],16,[Note])
ENDIF
= SQLDISCONNECT(hConn)
ENDIF
Các truy vấn khác
CLEAR
LOCAL lnConn
LOCAL lnPercent AS Int && Input parameters must be typed.
LOCAL lnOutput
lnPercent = 50
lnOutput = 0
* Make connection, assuming a local trusted connection.
lnConn = SQLCONNECT('Pubs')
IF m.lnConn > 0 && Success.
* Set the active database to PUBS.
SQLEXEC(m.lnConn, 'use pubs')
* Execute SELECT statement.
SQLEXEC(m.lnConn, 'SELECT * FROM authors', 'PubAuthors')
BROWSE
* Execute INSERT statement, get value of identity field.
SQLEXEC(m.lnConn, "INSERT INTO JOBS (job_desc, min_lvl, max_lvl);
VALUES ('Developer',75,150)")
SQLEXEC(m.lnConn, "SELECT SCOPE_IDENTITY()", "job_id")
? "ID for added Job is " + LTRIM(STR(job_id.exp))
* Execute DELETE statement. Get number of records affected.
SQLEXEC(m.lnConn, "DELETE FROM JOBS WHERE job_desc ='Developer'")
SQLEXEC(m.lnConn, "SELECT @@ROWCOUNT", 'rowcount')
? rowcount.exp, "record(s) deleted"
* Call a stored procedure with no parameters.
SQLEXEC(m.lnConn, 'sp_who', 'activeusers')
BROWSE
* Execute stored procedure with an INPUT parameter.
SQLEXEC(m.lnConn, 'exec byroyalty ?lnPercent','HalfOffAuthors')
* Create temp stored procedure with OUTPUT parameter and call it.
SQLEXEC(m.lnConn, "CREATE PROCEDURE #MyProc @outparam int OUTPUT AS;
SELECT @outparam=100")
SQLEXEC(m.lnConn, "exec #myProc ?@lnOutput")
? m.lnOutput
* Create a temp stored procedure with INPUT and OUTPUT parameters
* and call it.
SQLEXEC(m.lnConn, "CREATE PROCEDURE #MyProc2 " + ;
"@inputparam INT, " + ;
"@outparam int OUTPUT " + ;
"AS SET @outparam=@inputparam*10")
SQLEXEC(m.lnConn, "exec #myProc2 ?lnPercent, ?@lnOutput")
? m.lnOutput
* Get version information.
SQLEXEC(m.lnConn, 'SELECT @@VERSION','SQLVersion1')
? STRTRAN(SQLVersion1.Exp,CHR(0))
* Disconnect.
SQLDISCONNECT(m.lnConn)
ELSE
? "Unable to connect to SQL Server"
ENDIF
RETURN
Truy vấn tham số
Cũng giống như view từ xa, kỹ thuật SPT cũng cho phép gửi một truy vấn có
tham số. Các tham số là các biến nhớ và được để sau dấu chấm hỏi (?) như ví dụ sau:
LOCAL hConn, lcQuery, ldStart, ldStop
stConn= “DSN=NorthWind;” ;
+ "DATABASE=NORTHWIND;" ;
+ "Trusted_connection=Yes"
hConn=SQLSTRINGCONNECT(stConn)
IF hConn < 0
= MESSAGEBOX('Cannot make connection', 16, 'SQL Connect Error')
ELSE && successful connection
ldStart={^1998/1/1}
ldStop={^1998/12/31}
lcQuery=[SELECT C.CustomerID, O.OrderID,+ O.OrderDate, ];
+[C.CompanyName, C.City, C.Country ];
+ [ FROM dbo.Customers C INNER JOIN dbo.Orders O ];
+[ ON C.CustomerID = O.CustomerID ];
+[WHERE C.Country LIKE ( 'U%' ) ];
+[ AND O.OrderDate BETWEEN ?ldStart AND ?ldStop ];
+[ ORDER BY C.CustomerID]
lnResult=SQLExec(hConn,lcQuery, [Customers])
IF lnResult>0
SELECT Customers
BROWSE
USE IN Customers
ELSE
=MESSAGEBOX([An error occurred],16,[Note])
ENDIF
= SQLDISCONNECT(hConn)
ENDIF
2.3 Cập nhật kết quả về server
Khi dùng SPT thì mặc nhiên tập kết quả là một cursor chỉ đọc. Điều này có
nghĩa là dữ liệu đã được gửi từ server về, còn khi NSD thay đổi trên cursor thì Visual
FoxPro không gửi lại server. Để Visual FoxPro gửi các thay đổi trên tập kết quả của
truy vấn thì chúng ta cần sử dụng hàm CURSORSETPROP() để thay đổi một số thuộc
tính của cursor. Cụ thể, để truy vấn cập nhật ngược trở về server thì phải:
Thiết lập thuộc tính Table cho cursor để xác định cập nhật về server cho
bảng nào
Thiết lập thuộc tính KeyFieldList cho cursor để xác định các trường
khóa của cursor
Thiết lập thuộc tính UpdatableFieldList cho cursor để xác định danh
sách các trường có thể cập nhật ngược về server.
Thiết lập thuộc tính UpdateNameList cho cursor để xác định tên của các
trường (cột) nào của cursor tương ứng với tên của cột trong bản trên
server
Thiết lập thuộc tính SendUpdates của cursor về .T.
Hàm CURSORSETPROP() cho phép thiết lập thuộc tính cho các bảng hay
cursor của FoxPro, và có cú pháp là:
CURSORSETPROP( cProperty [, eExpression] [,cTableAlias | nWorkArea])
Trong đó:
cProperty: Chỉ định tên thuộc tính của bảng hay cursor.
eExpression: Chỉ định giá trị cho các thuộc tính được chỉ định ở cProperty
Dưới đây là một số thuộc tính cơ bản và giá trị của nó có thể nhận:
Ví dụ:
LOCAL hConn, lcQuery, ldStart, ldStop
stConn= "DSN=NorthWind;" ;
+ "DATABASE=NORTHWIND;" ;
+ "Trusted_connection=Yes"
hConn=SQLSTRINGCONNECT(stConn)
IF hConn < 0
= MESSAGEBOX('Cannot make connection', 16, 'SQL Connect Error')
ELSE && successful connection
ldStart={^1998/1/1}
ldStop=DATETIME()
lcQuery=[SELECT OrderID, OrderDate, ShipCity AS City];
+ [ FROM Orders WHERE OrderDate BETWEEN ?ldStart ];
+[ AND ?ldStop ORDER BY OrderID]
lnResult=SQLExec(hConn,lcQuery, [curOrders])
IF lnResult>0
CURSORSETPROP("Tables","Orders","curOrders")
CURSORSETPROP("KeyFieldList","OrderID"," curOrders")
CURSORSETPROP("UpdatableFieldList","OrderDate, City","
curOrders ")
CURSORSETPROP("UpdateNameList", ;
"OrderID Orders.OrderID, "+;
"OrderDate Orders.OrderDate, "+ ;
“City Orders.ShipCity”, " curOrders")
CURSORSETPROP("WhereType",1," curOrders")
CURSORSETPROP("Buffering",5," curOrders")
CURSORSETPROP("SendUpdates",.F.," curOrders")
REPLACE OrderDate WITH Date(), City WITH “New City”
CURSORSETPROP("SendUpdates",.T.," curOrders")
=TABLEUPDATE(.T.)
USE IN curOrders
ELSE
=MESSAGEBOX([An error occurred],16,[Note])
ENDIF
= SQLDISCONNECT(hConn)
ENDIF
Bạn đang đọc truyện trên: AzTruyen.Top