本文是《用 Visual FoxPro 與 SQL Server 構建 Client/Server 應用程式》系列的一部分,照例“遠程視圖”應不是開篇章節,但我們發現:在我們為網站準備的文章中有太多的理論性的東西,為了緩解這一矛盾,我們決定把“遠程視圖”提上來先寫。
當下最流行的 ADO 脫胎於 Visual FoxPro,在實際使用中兩者各有特色,所以不要小看 Visual FoxPro 在遠端資料處理上的能力,它絕對強大!讀者可以參看本站的《Microsoft Visual FoxPro 開發人員 ADO 快速入門》與《Visual FoxPro 漫談》。
我們希望通過連載的形式完成《用 Visual FoxPro 與 SQL Server 構建 Client/Server 應用程式》一文,非常希望得到您寶貴的建議。
說在前面
由於本文是在兩天之內趕出來的,構思不夠嚴密,我在選擇 SQL Server 端資料庫時犯了一個錯誤:Northwind 資料庫中絕大多數“字串”型欄位(列)使用了 nVarchar 型,Visual FoxPro 對此支援的不好(具體原因本站將另文論述)。以上可能造成示範程式不能正常工作,對此我們可以在 SQL Server 的 Enterprise Manager 中把有關欄位的的類型從 nVarchar 改為 Varchar。我建議把 Customers 表中的 CustomerID 和 Phone欄位的類型變化即可。同樣的,我們可以把 Employees 的 Notes 欄位類型變為 text。
不是我的錯
Visual FoxPro 的視圖設計器雖然能完成許多煩人的遠程視圖的操作,但對於特別複雜的遠程視圖可能會支援很差。在閱讀本文做實驗時,遇到以上問題請不要責怪作者。Visual FoxPro 的遠程視圖的功能非常強大的,大到工具程式“視圖設計器”不能很好的支援!
前言
Visual FoxPro 為 Client/Server 構架的應用提供了兩個內建的解決方案:遠程視圖(Remote Views)與 SPT(SQL pass through)。當然在Visual FoxPro中我們可以使用其它的遠端資料串連的方法,比如 ADO。所有這些解決方案都各有優劣,遠程視圖最大的好處就是它可以非常方便地與Visual FoxPro內建控制項綁定。每一個遠程視圖就是一個儲存於Visual FoxPro資料庫容器(DBC)的對象,是一句SQL-SELECT語句。遠程視圖通過ODBC(Open Database Connectivity)與異構資料庫通訊。
雖然本文的執行個體使用SQL Server 作為後端資料庫,但大家同樣可以使用其它資料來源作為後端資料庫,例如 Oracle,IBM DB2,Informix,Sybase,Microsoft Access,Excel,甚至是Visual FoxPro自己。使用遠程視圖操作遠端資料就像操作Visual FoxPro本機資料一般,以下我們將介紹這一偉大工具的初級應用。
串連-Connections
使用遠程視圖操作遠端資料的第一步就是建立與遠端資料源的通訊,這裡有好幾種方法可供選擇,請注意所有這些方法都使用 ODBC 與遠端資料串連。
這裡有一個非常簡單的遠程視圖,它的作用是:讀取 Northwind 資料庫中 Customers 表的記錄到遠程視圖 Vcustomers 中。
CREATE SQL VIEW Vcustomers ;
REMOTE CONNECTION Northwind ;
AS SELECT * From Customers
*先別試用這條語句,因為串連還沒有建立
在上述命令的第二行我們告訴Visual FoxPro使用串連 Northwind 與 SQL Server 通訊。在運行上面的語句時,Visual FoxPro將在兩個地方尋找這個串連:
-
當前 資料庫容器(DBC)中查看是否存在資料庫“連線物件”——Northwind。筆者稱之為基於 DSN 的連線物件。
-
如果沒有發現,Visual FoxPro將在客戶機的 OCBC Data Source Names(DSNs)中查看是否存在串連 Northwind。筆者稱之為 DSN 串連。
建立 DSNs 串連
建立串連的最快、最方便的方法是建立DSNs,您可以在控制台中開啟 ODBC 控制器,如圖1。
圖 1. ODBC Data Source Administrator 面板
我們發現有三種DSN 串連:
使用者型DSN、系統型DSN、檔案型DSN。其中使用者型只對建立它的使用者有效,譬如你以 Administrator 的身份登入系統並建立了一個使用者DSN,那麼除非你以 Administrator 登入系統否則你不能使用這一DSN;系統型則對當前用機器所有使用者生效,無論你以什麼身份登入系統;檔案型DSN實際上是一個以DSN為尾碼名的文字檔。從 Visual FoxPro 的角度,筆者把這三種 DSN 分成兩類:
-
使用者型、系統型 DSN。它可以單獨作為串連為遠程視圖使用;也可以作為“基於 DSN 連線物件”的基礎,“基於 DSN 連線物件”依賴於使用者型或是系統型 DSN。
-
檔案型 DSN。它不可以單獨作為串連為遠程視圖使用;它可以為設計“基於字串的連線物件”提供資料,但“基於字串的連線物件”不依賴於檔案型 DSN。
我們先建立一個系統型 DSN。
在 ODBC Data Source Administrator 面板中選中 “System DSN”頁,按“Add”鍵,再選擇 SQL Server 驅動程式,按“完成”按鈕。出現圖2。
圖 2. 設定 DSN 的名稱及伺服器
這裡我們選擇“(local)”,注意如果系統將嘗試串連目標伺服器如果無法串連將報錯,如果順利的話您將看到圖3的畫面,要求選擇使用者認證方式,這裡我們選擇 SQL Server 與 Windows 混合認證方式,並輸入登入SQL Server的使用者名稱:“sa”,口令為空白。
圖 3. 設定 DSN 的登入資訊
如果順利畫面4將出現在螢幕上,這裡有一個選項要特別的注意,就是選擇目標資料庫。這裡我們當然是選“Northwind”。
圖 4. 設定 DSN 的登入資料庫
廢話就不多說了,如果一些順利,這條叫“Northwind”的System DSN 就建成了。
在Visual FoxPro的命令視窗中建立如下語句:
CREATE DATABASE Northwind
*建立本機資料庫容器,儲存資料庫物件。
CREATE SQL VIEW VCustomers ;
REMOTE CONNECTION Northwind ;
AS SELECT * FROM Customers
*建立遠程視圖,注意這個視圖是資料庫(DBC)的一個對象,所以必須先建立DBC
USE VCustomers
*開啟遠程視圖
BROWSE
*瀏覽遠程視圖
建立資料庫容器(DBC)中的“連線物件”
記得在前文我們講過串連可以存在於兩個地方,就是 DSNs與DBC,那麼DSN與基於DSN的連線物件有什麼區別?
基於DSN的連線物件可以為數個遠程視圖共用,而DSN串連不可以。我們知道,每一條與SQL Server的串連都是要收費的,共用串連就可以省錢;我們還知道,SQL Server管理每條串連大約要花去24K的記憶體空間,有人講:24K不多,但您別忘了SQL Server是伺服器,不只是您一個人使用它——東一條串連、西一條串連——系統效率一定會受影響。因此無論從開發成本還是系統工作效率的角度,共用串連都是開發人員必然的選擇。
為了說明什麼是共用串連,為了證明DSN串連不能為試圖共用,我們做以下實驗:
CREATE SQL VIEW VOrders ;
REMOTE CONNECTION Northwind SHARE;
AS SELECT * FROM Orders
*建立一個遠程視圖,仍然使用名稱為Northwind 的DSN串連
DBSETPROP('VCustomers', 'View', 'ShareConnection', .T.)
USE VCustomers IN 0
*開啟剛才的那個視圖
USE VOrders IN 0
*開啟建立的遠程視圖
?CURSORGETPROP("ConnectHandle", "VCustomers")
*顯示 1
?CURSORGETPROP("ConnectHandle", "VOrders")
*顯示 2
*這兩個遠程視圖(游標)的串連控制代碼不是同一個。如果一條串連被共用了,那麼這兩個游標的串連控制代碼應是同一個數字;這兩個視圖雖然使用同一個 DSN 但實際上它們沒有共用串連。
為了使用共用串連著一特性,我們建立“基於 DSN 的 連線物件”:
CREATE CONNECTION Northwind DATASOURCE Northwind
以上這條串連是建立在上面我們建立的DSN串連之上的,串連成為資料庫容器的一個對象了。但注意:這種連線物件並不能擺脫DSN的控制,它的串連資訊仍然儲存在DSN中。
為了在視圖間共用串連,我們必須設定設圖的共用串連的屬性,凡是參與共用串連的遠程視圖都必須具備共用串連的屬性,否則共用串連還是不能實現。設定共用串連的方法有兩種:
-
建立視圖設計使用關鍵字 SHARE。如:
CREATE SQL VIEW VOrders ;
REMOTE CONNECTION Northwind SHARE;
AS SELECT * FROM Orders
-
設定已視圖的ShareConnection的屬性為.t.。如:
DBSETPROP('VCustomers', 'View', 'ShareConnection', .T.)
為了證明串連共用的特性我們執行以下代碼:
USE VCustomers IN 0
USE VOrders IN 0
?CURSORGETPROP("ConnectHandle", "VCustomers")
*顯示:1
?CURSORGETPROP("ConnectHandle", "VOrders")
*顯示:1
我們已經學習了怎樣建立“基於 DSN 的連線物件”,並瞭解了串連共用。仔細思考,您也許會發現“基於 DSN 的連線物件”存在下列問題:
-
運行時(RUN TIME)的可控性差。比如我們希望應用程式在不同的條件下使用不同的使用者登入資料庫伺服器、或是不同的資料庫,是不是要建立 N 個 DSN 以及 N 個“基於 DSN 的串連”?太可怕了!
-
由於“基於 DSN 的串連”對 DSN 的依賴性很強,例如:使用者刪除或是更改了 DSN 資訊,那麼我們應用程式就無法正常運行了!
為瞭解決以上問題,Visual FoxPro 提出了“連接字串的概念”。筆者稱之為:基於字串的串連。一個連接字串基本上包括五個主要內容:ODBC 磁碟機、伺服器、使用者名稱、登入名稱、資料庫。(針對 SQL Server 而言)
CREATE CONNECTION Northwind2 ;
CONNSTRING "DRIVER=SQL;UID=sa;DATABASE=Northwind;SERVER=(local);PWD="