程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 混合編程:嵌入式SQL與主語言的通信

混合編程:嵌入式SQL與主語言的通信

編輯:關於SqlServer
將SQL嵌入到高級語言中混合編程,程序中會含有兩種不同計算模型的語句:

  1、SQL語句:描述性的面向集合的語句;負責操縱數據庫。

  2、高級語言語句:過程性的面向記錄的語句;負責控制程序流程。

  工作單元之間的通信方式:

  1、 SQL通信區:向主語言傳遞SQL語句的執行狀態信息;主語言能夠據此控制程序流程。

  2、主變量:

  (1) 主語言向SQL語句提供參數。

  (2) 將SQL語句查詢數據庫的結果交主語言進一步處理。

  3、游標:解決集合性操作語言與過程性操作語言的不匹配。

  一、SQL通信區

  SQLCA:SQL Communication Area。SQLCA是一個數據結構。

  SQLCA的用途:

  SQL語句執行後,DBMS反饋給應用程序信息:

  (1)描述系統當前工作狀態。

  (2)描述運行環境。

  這些信息將送到SQL通信區SQLCA中,應用程序從SQLCA中取出這些狀態信息,據此決定接下來執行的語句。

  SQLCA的使用方法:

  用EXEC SQL INCLUDE SQLCA加以定義。SQLCA中有一個存放每次執行SQL語句後返回代碼的變量SQLCODE。如果SQLCODE等於預定義的量SUCCESS,則表示SQL語句成功,否則表示出錯;應用程序每執行完一條SQL 語句之後都應該測試一下SQLCODE的值,以了解該SQL語句執行情況並做相應處理。

  例:在執行刪除語句DELETE後,不同的執行情況,SQLCA中有不同的信息:

  · 違反數據保護規則,操作拒絕。

  · 沒有滿足條件的行,一行也沒有刪除。

  · 成功刪除,並有刪除的行數。

  · 無條件刪除警告信息。

  · 由於各種原因,執行出錯。

  二、主變量

  嵌入式SQL語句中可以使用主語言的程序變量來輸入或輸出數據。在SQL語句中使用的主語言程序變量簡稱為主變量(Host Variable)。

  主變量的類型:

  1、 輸入主變量:由應用程序對其賦值,SQL語句引用。

  2、 輸出主變量:由SQL語句賦值或設置狀態信息,返回給應用程序。

  3、 一個主變量有可能既是輸入主變量又是輸出主變量。

  4、 一個主變量可以附帶一個指示變量(Indicator Variable)。

  5、 指示變量一個整型變量,用來“指示”所指主變量的值或條件。

  指示變量的用途:輸入主變量可以利用指示變量賦空值;輸出主變量可以利用指示變量檢測出是否空值,值是否被截斷。

  在SQL語句中使用主變量和指示變量的方法:

  1、 說明主變量和指示變量

  BEGIN DECLARE SECTION
  .........
  ......... (說明主變量和指示變量)
  .........
  END DECLARE SECTION

  2、 使用主變量

  說明之後的主變量可以在SQL語句中任何一個能夠使用表達式的地方出現,為了與數據庫對象名(表名、視圖名、列名等)區別,SQL語句中的主變量名前要加冒號(:)作為標志。

  3、 使用指示變量

  · 指示變量前也必須加冒號標志。

  · 必須緊跟在所指主變量之後。

  · 在SQL語句之外(主語言語句中)使用主變量和指示變量的方法。

  · 可以直接引用,不必加冒號。

三、游標(cursor)

  游標是系統為用戶開設的一個數據緩沖區,存放SQL語句的執行結果。每個游標區都有一個名字,用戶可以用游標逐一獲取記錄,並賦給主變量,交由主語言進一步處理。

  為什麼要使用游標?

  1、 SQL語言與主語言具有不同數據處理方式。

  2、 SQL語言是面向集合的,一條SQL語句原則上可以產生或處理多條記錄。

  3、 主語言是面向記錄的,一組主變量一次只能存放一條記錄,僅使用主變量並不能完全。

  4、 滿足SQL語句向應用程序輸出數據的要求。

  5、 嵌入式SQL引入了游標的概念,用來協調這兩種不同的處理方式。

  下面用個程序詳解:

  #include
  #include
  EXEC SQL BEGIN DECLARE SECTION; /*主變量說明開始*/

  char deptname[64];
  char HSno[64]
;
  char HSname[64]
;
  char HSsex[64]
;
  int
HSage;
  int
NEWAGE;
  long
SQLCODE;
  EXEC SQL END DECLARE SECTION; /*主變量說明結束*/

  EXEC SQL INCLUDE sqlca; /*定義SQL通信區*/
 /*************************************************************************/
  int main(void) /*C語言主程序開始*/
  {
  
int count = 0;
  char yn; /*變量yn代表yes或no*/

  printf("Please choose the department name(CS/MA/IS): ");
  scanf("%s", deptname); /*為主變量deptname賦值*/

  EXEC SQL CONNECT TO HP-08D6CXF128B\SQL2000 USER sa; /*連接數據庫TEST*/
  EXEC SQL DECLARE SX CURSOR FOR /*定義游標*/
  SELECT Sno, Sname, Ssex, Sage /*SX對應語句的執行結果*/
  FROM Student
  WHERE SDept =
:deptname;
  EXEC SQL OPEN SX; /*打開游標SX便指向查詢結果的第一行*/

  for ( ; ; ) /*用循環結構逐條處理結果集中的記錄*/
  {
  
EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex,:HSage;
  /*推進游標,將當前數據放入主變量*/

  if (sqlca->sqlcode != 0) /* sqlcode != 0,表示操作不成功*/
  break; /*利用SQLCA中的狀態信息決定何時退出循環*/
  if(count++ == 0) /*如果是第一行的話,先打出行頭*/
  printf("\n%-10s %-20s %-10s %-10s\n", "Sno", "Sname", "Ssex", "Sage");
  printf("%-10s %-20s %-10s %-
10d\n", HSno, HSname, HSsex, HSage);
  /*打印查詢結果*/

  printf("UPDATE AGE(y/n)?"); /*詢問用戶是否要更新該學生的年齡*/
  do{
  scanf("
%c",&yn);
  }
  while(yn != 'N' && yn != 'n' && yn != 'Y' && yn != 'y'
);
  if (yn == 'y' || yn == 'Y') /*如果選擇更新操作*/

  {
  printf("INPUT NEW AGE:");
  scanf("
%d",&NEWAGE); /*用戶輸入新年齡到主變量中*/
  EXEC SQL UPDATE Student /*嵌入式SQL*/
  SET Sage = :NEWAGE
  WHERE CURRENT OF
SX ;
  } /*對當前游標指向的學生年齡進行更新*/

  }
  
EXEC SQL CLOSE SX; /*關閉游標SX不再和查詢結果對應*/
  EXEC SQL COMMIT WORK; /*提交更新*/
  EXEC SQL DISCONNECT TEST; /*斷開數據庫連接*/
  }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved