通過工具建立串連
以上我們都是通過命令的方式建立串連,現在我們將使用Visual FoxPro提供的串連設計器建立串連。上文我們講到:連線物件分為兩類:“基於 DSN 的連線物件”和“基於字串的連線物件”。圖5:
-
在串連設計器中選擇“資料來源、使用者標識、密碼”就說明在建立“基於 DSN 的連線物件”,在“資料來源”列表框中可選擇當前可用的使用者型、系統型 DSN。
-
在串連設計器中選擇“串連串”就說明在建立“基於字串的連線物件”,為了快速、正確的設計連接字串,我們可以開啟檔案型 DSN 參考,注意:“基於字串的連線物件”不依賴檔案型 DSN。
圖 5. 串連設計器
串連屬性的設定
從串連設計器的畫面上我們可以發現很多串連屬性,他們代表什麼意思呢?在講述這些問題之前,我想告訴大家:所有這些屬性的設定都可以通過DBSETPROP()函數,所有這些屬性值的擷取都可以通過DBGETPROP()函數得到。下面,我們簡要介紹幾個屬性:
-
非同步執行。預設值為 .F.。同步執行是指:通過串連傳送到後端的命令會被一句一句地執行,前一句沒有執行完畢後一句就不會被執行;而同步執行是指:當通過串連發出命令後,不管後端是否完成並返回結果,用戶端程式可以繼續往下走。
-
逾時間隔-空閑(分)。預設值是 0。設定一個非 0 值時,一個串連如果在這段時間內沒被使用,Visual FoxPro 將使它休眠,再次使用該串連時 Visual FoxPro會啟用它。注意使用該屬性,因為它常常使您的應用程式產生不明不白的錯誤,如"Connectivity error: unable to retrieve specific error information. Driver is probably out of resources."實際上現在 ODBC 提供了 POOL 的功能,這些問題可由 ODBC 自行解決,我們不用操心。
-
逾時間隔-串連(秒)。預設值是 0。設定一個非 0 值時,指在這個時間段內Visual FoxPro將試圖串連到伺服器,如果不成功,Visual FoxPro將產生一個錯誤。
-
顯示 ODBC 登入提示。在應用程式中,我們總不希望有系統彈出登入視窗,這樣於形象不利、於程式的安全性不利,特別是設計 COM 物件時,由於無人看護,更不希望登入視窗的彈出,Visual FoxPro 為我們提供了三種選擇,筆者經常使用“從不顯示”。
-
顯示錯誤資訊。如果設定為 .t.,任何 ODBC 錯誤將以 Messagebox 視窗顯示出來;反之,ODBC 錯誤有使用者自行處理。顯然我們基本上使用預設設定 .f.。
提示:在Visual FoxPro中很多關於資料處理方面的設定,(如:set delete)都是限於資料工作期的,而串連被啟用後可以在多個資料工作期內公用。
遠程視圖
弱水三千,取一瓢飲——條件視圖
在前文我們已經建立了兩個遠程視圖,您也許發現這種整個把遠端資料表讀取過來的做法執行效果很好,其實不然。我有兩大理由:
-
設想如果後端表很大(Customers 只有 91 條記錄),有幾萬、幾十萬條記錄,結果會這樣?
-
設想如果網路使用者很多,網路很繁忙,結果會怎樣?
Client\Server設計的一個重要的課題就是使網路流量最小化,所以在設計遠程視圖時就要考慮這一解決問題。我們的想法是使遠程視圖僅下載有必要的資訊,這就叫:弱水三千,取一瓢飲。例如:
CREATE SQL VIEW VCustomers
REMOTE CONNECTION Northwind SHARE ;
AS SELECT * FROM Customers
WHERE customerid LIKE 'ALFKI'
我們在 WHERE子句中加入條件“customerid LIKE 'ALFKI'”,現在我們發現只有一條記錄從遠端被下載。您也與已經發現這中間的不足:這個遠程視圖太死板了——只能為 Customerid 類似於'ALFKI'的記錄提供服務,是不是可以把 'ALFKI'作為一個參數,供使這個遠程視圖更靈活,服務面更廣。
可以,Visual FoxPro支援這樣的遠程視圖:
CREATE SQL VIEW VCustomers ;
REMOTE CONNECTION Northwind SHARE ;
AS SELECT * FROM Customers ;
WHERE customerid LIKE cCustomerID
如果您開啟遠程視圖或對已開啟的遠程視圖執行REQUERY()、REFRESH()函數,Visual FoxPro會尋找是由存在名為cCustomerID的變數。如果存在,Visual FoxPro 自動把變數值填入遠程視圖的SQL語句中;如果變數不存在,Visual FoxPro將彈出如下視窗詢問變數值。
在實際開發應用程式中,我們會經常實現設定遠程視圖參數,在需要其它資訊時,改變參數值,再用REQUERY()函數重新整理用戶端的資料;遠程視圖參數不僅可以填入普通資料,還可以使用統配符,如下:
cCustomerID='ALFKI'
USE Vcustomers
BROWSE
cCustomerID='%B%'
REQUERY('Vcustomers')
BROWSE
這裡有以下問題點大家必須注意:
-
遠程視圖參數只能在WHERE字句中設定,其他的串連子句、分組字句、排序子句都不支援這一特性。比如不可以出現 Order by ?cOrder。(有傳言說 Visual FoxPro 7 支援參數加入排序子句,但筆者還未及嘗試)。
-
一個遠程視圖可以設定多個參數。執行個體見下面的代碼。
-
遠程視圖的SELECT-SQL語句必須是以後端資料庫的文法為標準。例如,SQL Server以單引號確認字串,而Visual FoxPro可使用雙引號、方括弧、單引號確認字串,那麼如下語句是錯誤:
CREATE SQL VIEW VCustomers REMOTE CONNECTION Northwind SHARE ;
AS SELECT * FROM Customers WHERE customerid LIKE "ALFKI"
又如,Visual FoxPro中刪除字元型欄位的空格可使用ALLTR()函數,但遠程視圖的SELECT-SQL中不能用任何Visual FoxPro的函數,所以要實現上述功能,應如下使用SQL Server的函數:
CREATE SQL VIEW VCustomers REMOTE CONNECTION Northwind SHARE ;
AS SELECT customerid,LTRIM(RTRIM(CompanyName)) FROM Customers WHERE customerid LIKE 'ALFKI'
-
第三點中我們強調了遠程視圖構建時必須使用後端資料庫認識的Select-SQL。當遠程視圖被開啟,成為Visual FoxPro的游標時,就可以對它使用Visual FoxPro的命令與函數。
CREATE SQL VIEW VEmployees;
REMOTE CONNECTION Northwind SHARE
AS SELECT EmployeeID,Birthdate FROM Employees
WHERE BirthDate >?dBirthdate1 AND BirthDate <?dBirthdate2
dBirthdate1='19540101'
dBirthdate2='19601231'
USE VEmployees
BROWSE
*本例對日期型欄位Birthdate使用了兩個參數,並請注意日期型參數的傳遞。
CREATE SQL VIEW VEmployees1;
REMOTE CONNECTION Northwind SHARE;
AS SELECT EmployeeID, BirthDate, Country FROM Employees;
WHERE birthDate > ?dBirthdate AND Country = ?cCountry
dBirthdate='19601231'
cCountry='uk'
USE VEmployees1
BROWSE
*本例對兩個欄位設定了參數
只下載有用的欄位
上文中我們使用 SELECT * 從遠端一古腦兒把所有列都下載到客戶機,這樣做不好。原因如下:
-
對遠端資料操作時並不是所有的列(欄位)都會被我們用到,特別是備忘欄位、大二進位欄位。
-
在視圖階段就可以通過計算有關列得到更有用的資訊,見下面的代碼。
-
明確指定列資訊有助於Visual FoxPro對遠端資料表的版本控制。如果使用 SELECT *,那麼只有在遠端資料表增加欄位時Visual FoxPro才知道,其他如減少、變更列的結構Visual FoxPro都不會知道。
例如:遠端資料表中有FirstName,LastName列,我們在製作報表時只需要全名就可以了,那麼我們解可以將它們相加成為一個新的列。
CREATE SQL VIEW VEmployees1 ;
REMOTE CONNECTION Northwind SHARE ;
AS SELECT EmployeeID, FirstName +' '+ LastName AS Name, Title ;
FROM Employees
多表串連形成的遠程視圖
遠程視圖不僅支援遠程一個表的操作,它還支援多表串連,如下:
CREATE SQL VIEW VEmployeeTerritories ;
REMOTE CONNECTION Northwind SHARE ;
AS SELECT Territories.TerritoryID, Territories.TerritoryDescription, Employees.EmployeeID,;
Employees.LastName, Employees.FirstName;
FROM Territories INNER JOIN;
EmployeeTerritories ON ;
Territories.TerritoryID = EmployeeTerritories.TerritoryID INNER JOIN;
Employees ON EmployeeTerritories.EmployeeID = Employees.EmployeeID
遠程視圖還支援自串連,如下:
CREATE SQL VIEW VEmployeeReportTO ;
REMOTE CONNECTION Northwind SHARE ;
AS SELECT Employees.EmployeeID as 領導工號,;
Employees.FirstName+' '+ Employees.LastName as 領導,;
Employees_a.FirstName +' '+ Employees_a.LastName as 下屬,;
Employees_a.ReportsTo as 上級領導工號;
FROM Employees Employees INNER JOIN;
Employees Employees_a ON ;
Employees.EmployeeID = Employees_a.ReportsTo;
ORDER BY Employees_a.ReportsTo
從上面的語句大家可以發現:Visual FoxPro中的 SQL 與SQL Server 中的 SQL 十分相似,這方便了學習,但千萬別陷入了“溫柔陷阱”!