張華,張淼,鄭宏珍
(哈爾濱工業大學,山東 威海 264209)
收稿日期:2006-02-19
作者簡介:張華(1978-),男,理學碩士,研究方向:Web資訊提取,ERP,多媒體技術;張淼,女,碩士;鄭宏珍,女,博士生,副教授,碩士導師。
摘要:針對嵌入式SQL編程技術,本文論述了C程式中嵌入SQL語句的代碼格式,嵌入式SQL語言與C語言之間的通訊方式以及嵌入式SQL應用程式在VC++6.0中的編譯過程,並給出了直觀的代碼執行個體。
關鍵詞:C語言;SQL Server;嵌入式SQL;VC++6.0
中圖法分類號:TP311 文獻標誌碼:A 文章編號:1009-3044(2006)14-0102-01
Programming Embedded SQL for C-language and Database of SQL Server
ZHANG Hua, ZHANG Miao, ZHENG Hong-zhen
(School of Computer Science and Technology, Weihai 264209, China)
Abstract: As to programming technology of Embedded SQL, the code format of Embedded SQL in C applications and the communication modes between C-language and sentences of Embedded SQL were discussed in the paper. The compiling processes of Embedded
SQL Application based on C-language and Database of SQL Server was also shown detailedly in VC++6.0. At last, an example was given in order to attaining an intuitionistic understanding of Embedded SQL programming for C-language and Database of SQL Server.
Key words: C-language; SQL Server; embedded SQL; VC++6.0
1 引言
基於資料庫的操作中,許多交易處理應用都是過程性的,需要根據不同的條件來執行不同的任務,因此單純用SQL語言是很難實現這類應用的。為瞭解決這一問 題,將SQL語言嵌入到某種進階語言中使用,利用進階語言的過程性結構來彌補SQL語言實現複雜應用方面的不足,這種方式下使用的SQL語言稱為嵌入式 SQL(Embedded SQL),而嵌入SQL的進階語言稱為主語言或宿主語言[1]。下面就用於C語言與SQL Server的嵌入式編程技術給以詳細論述。
2 C程式中嵌入SQL語言的代碼格式
在C程式中,為了能夠區分SQL語句與C語言語句,所有SQL語句都必須加首碼EXEC SQL。例如一條SQL語句:"DROP TABLE emp",嵌入到C程式中,應寫作"EXEC SQL DROP TABLE emp"。
3 C語言與SQL語言的通訊
嵌入SQL的C語言應用程式中,SQL語句負責操縱資料庫,具有面向集合的性質,C語句負責控製程序流程,具有面向過程的性質。因此,弄清這兩種不同計算模型的語句間的通訊方式是至關重要的[2]。
3.1 通過SQLCA通訊結構通訊
應用程式執行時,每執行一條SQL語句,就返回一個狀態符和一些反映SQL語句執行情況的附加資訊。這些資訊有助於分析應用程式的錯誤所在,它們都存放在 sqlca.h的SQLCA結構體中。SQLCA是SQL與宿主語言的通訊區,其常用的結構成員sqlcode用於保留最近執行的SQL語句的狀態 碼,sqlerrmc用來保留與sqlcode中的狀態代碼對應 的錯誤資訊文本。嵌入SQL語句的C程式都必須要加入一條語句,即EXEC SQL INCLUDE sqlca.h。
3.2 通過主變數通訊
負責SQL語句與C語句資料交換的是主(Host)變數,這種變數既可以用在SQL語句中,又可以用在C語句中。主變數必須在DECLARE SECTION中說明,說明格式與舉例詳見表1。
3.3 通過遊標通訊
一條SQL語句原則上可以產生或處理多條記錄,而一組主變數一次只能存放一條記錄。因此,僅使用主變數並不能完全滿足SQL語句嚮應用程式輸出資料的要 求。為瞭解決這個問題,嵌入式SQL引入了遊標的概念來協調這兩種不同的處理方式。遊標是系統開設的一個資料緩衝區,存放SQL語句的執行結果集。每個遊 標區都有一個名字,使用者可以用SQL語句逐一從遊標中擷取記錄,並賦給主變數,交由主語言進一步處理。與遊標有關的命令共有四條,功能與格式詳見表2。
表1:主變數聲明格式及舉例
表2:遊標命令及格式
嵌入SQL的C應用程式具體到VC++6.0、SQL Server2000下調試可分為五步:(1)環境初始化;(2)先行編譯;(3)編譯;(4)串連;(5)運行。下面就其中重要的操作方法給以詳細說明。
4.1 環境初試化
(1)SQL Server2000為其嵌入式SQL提供了一些特殊的介面;預設的安裝方式並沒有安裝這些介面;因此,需要把devtools.rar解壓到SQL Server的系統目錄下;如果作業系統安裝在C盤,則SQL Server的系統目錄是:C:\Program Files\Microsoft SQL Server。
(2)初始化Visual C++6.0編譯器環境。在命令列方式下運行檔案:\Microsoft Visual Studio\VC98\Bin\vcvars32.bat。
(3)初始化SQL Server的先行編譯環境。在命令列方式下運行檔案:\Devtools\samples\esplc\setenv.bat。
(4)VC++6.0環境配置。具體配置分為如下三步[3]:
[1]Tools->options->directories->Include
Files: C:\Program Files\Microsoft SQL Server\devtools\include
[2]Tools->options->directories->Lib
Files: C:\Program Files\Microsoft SQL Server\devtools\x86lib
[3]project->Settings->Link->Object/Library Modules,添加庫檔案:SQLakw32.lib,Caw32.lib。這兩個檔案之間用空格分開。
4.2 先行編譯
C語言編譯器不能識別應用程式中的SQL語句,需要經過預先處理程式將其轉換成C語句。SQL Server的預先處理程式是nsqlprep.exe。nsqlprep.exe在SQL Server安裝目錄的MSSQL\Binn下。若SQL Server資料庫採用的是預設安裝方式,則需要把binn.rar的內容拷貝到指定目錄下。nsqlprep.exe的常用文法格式與相關說明見表3。
表3:nsqlprep文法格式與相關說明
4.3 編譯、連結與運行
在VC++6.0中建立一個“WIN32 Console Application”類型的Project,然後將先行編譯產生的c檔案加入Project,編譯串連即可產生訪問SQL Server的可執行程式[4]。Visual C++6.0進行編譯串連時需要用到動態連結程式庫SQLakw32.dll與SQLaiw32.dll;儘管這兩個檔案已經隨同binn.rar被拷貝到 SQL Server安裝目錄的MSSQL\Binn檔案夾下,但仍然需要把它們的路徑加到系統路徑變數中,以使得程式運行時能找到它們,具體添加方法如下:
方法1:把這兩個檔案拷貝到作業系統目錄下的system32子目錄中。
方法2:“我的電腦”->“屬性”->“進階”->“環境變數”->“path,編輯”,在變數值中加入路徑值;新路徑已有路徑間用“;”間隔。
5 程式執行個體
下面給出帶有嵌入式SQL的一段C程式,一提高對嵌入式SQL應用程式的感性認識。
......
EXEC SQL INCLUDE sqlea.h;/*(1)定義SQL通訊區 */EXEC SQL BEGIN DECLARE SECTION;/*(2)說明主變數開始*/CHAR title_id(7);CHAR title(81);INT royalty;EXEC SQL END DECLARE SECTION;/*說明主變數結束*/main(){ EXEC SQL DECLARE C1 CURSOR FOR/*(3)遊標操作(定義遊標)*/ SELECT tit_id,tit,roy FROM titles;/*從title表查tit_id,tit,roy*/ for(;;) { /*(5)遊標操作(將當前資料放入主變數並推進遊標指標)*/ EXEC SQL FETCH C1 INTO:title_id:title,:royalty; /*(6)利用SQLCA中的狀態資訊決定何時推出迴圈*/ if(sqlca.sqlcode<>SUCCESS) break;/*列印查詢結果*/ printf("Title ID:%s, Royalty:%d",:title_id,:royalty"); printf("Title:%s",:title); } EXEC SQL CLOSE C1;/*(7)遊標操作(關閉遊標)*/}
6 總結
當一個程式既要訪問資料庫,又要處理資料時,把SQL語言嵌入到宿主語言中,將SQL語言訪問資料庫的功能和宿主語言的資料處理功能相結合,是解決該問題 的有效途徑。需要說明的是用於C語言與SQL Server的嵌入式SQL編程不是安全執行緒的[5]。如果在C程式的一個線程應用中使用嵌入式SQL,那麼應該僅僅在一個單一線程中調用嵌入式SQL, 最好在主線程中使用。
參考文獻:
[1]薩師煊,王珊。資料庫系統概論[M]。高等教育出版社。2000,2.
[2]楊安祺,單振芳,楊競瀾。基於C/C++與ORACLE9i的嵌入式SQL編程技術[M]。微電腦資訊。2005,2。
[3]丁益祥。嵌入式SQL語言在VC中的實現[J]。武漢科技學院學報。2003,8。
[4]顏昌學。一種嵌入式SQL語言在VC++中的實現方法[J]。西南民族大學學報。2003,6。
[5]ESQL/C資料。http://www.ddvip.net/OS/scounix/index2/57.htm[EB/OL]。2005,3。
[6](美)Robison.L.著;黃惠菊,張捷等譯。輕鬆掌握用Visual C++6對資料庫編程[M]。電子工業出版社。1999,6。
[7]袁鵬飛。SQL Server 7.0資料庫管理與應用開發[M]。人們郵電出版社。1999,5。