第九講 嵌入式SQL語(yǔ)言之基本技巧

嵌入式SQL語(yǔ)言

為什么需要嵌入式SQL語(yǔ)言?

交互式SQL本身不夠靈活, 對(duì)于普通用戶來(lái)說(shuō), 復(fù)雜的查詢掌握起來(lái)太難, 開(kāi)發(fā)應(yīng)用程序很有必要. 而且查詢本身具有復(fù)雜性, 若是能結(jié)合高級(jí)語(yǔ)言的流程控制等特性, 將會(huì)有很大優(yōu)勢(shì).

高級(jí)語(yǔ)言中使用嵌入式語(yǔ)言需要解決的問(wèn)題

程序與數(shù)據(jù)庫(kù)連接

SQL語(yǔ)句在執(zhí)行過(guò)程中,必須有提交和撤消語(yǔ)句才能確認(rèn)其操作結(jié)果.

  • SQL執(zhí)行的提交:
    exec sql commit work;
  • SQL執(zhí)行的撤消:
    exec sql rollback work;

為什么需要提交和撤銷?
先了解一下事務(wù)的概念:

事務(wù)

(從應(yīng)用程序員角度)是一個(gè)存取或改變數(shù)據(jù)庫(kù)內(nèi)容的程序的一次執(zhí)行,或者說(shuō)一條或多條SQL語(yǔ)句的一次執(zhí)行被看作一個(gè)事務(wù).

事務(wù)一般是由應(yīng)用程序員提出,因此有開(kāi)始和結(jié)束, 結(jié)束前需要提交或撤消。

Begin Transaction
exec sql …
…
exec sql …
exec sql commit work | exec sql rollback work
End Transaction

在嵌入式SQL程序中,任何一條數(shù)據(jù)庫(kù)操縱語(yǔ)句(如exec sql select等)都會(huì)引發(fā)一個(gè)新事務(wù)的開(kāi)
始,只要該程序當(dāng)前沒(méi)有正在處理的事務(wù)。而事務(wù)的結(jié)束是需要應(yīng)用程序員通過(guò)commit或
rollback確認(rèn)的。因此Begin Transaction和End Transaction兩行語(yǔ)句是不需要的。

事務(wù), 就是提供一組操作, 要么全部執(zhí)行, 要么全部不執(zhí)行, 保證這個(gè)這組操作過(guò)程的完整性.

事務(wù)的特性:

  • 原子性Atomicity
    DBMS能夠保證事務(wù)的一組更新操作是原子不可分的,即對(duì)DB而言,要么全做,要么全不做

  • 一致性Consistency
    DBMS保證事務(wù)的操作狀態(tài)是正確的,符合一致性的操作規(guī)則,它是進(jìn)一步由隔離性來(lái)保證的

  • 隔離性Isolation
    DBMS保證并發(fā)執(zhí)行的多個(gè)事務(wù)之間互相不受影響。例如兩個(gè)事務(wù)T1和T2, 即使并發(fā)執(zhí)行,也相當(dāng)于或者先執(zhí)行了T1,再執(zhí)行T2; 或者先執(zhí)行了T2, 再執(zhí)行T1

  • 持久性Durability: DBMS保證已提交事務(wù)的影響是持久的,被撤銷事務(wù)的影響是可恢復(fù)的.

嵌入式SQL示例:

#include <stdio.h>
#include “prompt.h”
exec sql include sqlca;  // SQLCA: SQL communication, Area SQL通信區(qū)
char cid_prompt[ ] = "Please enter customer id: ";
int main()
{ 
    exec sql begin declare section;       // 變量聲明
    char cust_id[5], cust_name[14];    
    float cust_discnt;
    char user_name[20],user_pwd[20];
    exec sql end declare section;

    exec sql whenever sqlerror goto report_error;    // SQL錯(cuò)誤捕獲語(yǔ)句
    exec sql whenever not found goto notfound;       // SQL錯(cuò)誤捕獲語(yǔ)句

    strcpy(user_name, "poneilsql");    // 連接數(shù)據(jù)庫(kù)
    strcpy(user_pwd, "*****");
    exec sql connect :user_name identified by :user_pwd;

    while((prompt(cid_prompt, 1, cust_id, 4)) >=0) {
        exec sql select cname,discnt
            into :cust_name, :cust_discnt
            from customers where cid=:cust_id;
        exec sql commit work;        // SQL Commit Wort

        printf("Customer’s name is %s and discount is %5.1f\n", cust_name,cust_discnt);
        continue;

        notfound: printf("Can’t find customer %s, continuing\n", cust_id);
    }
    exec sql commit release;
    return 0;

    report_error:
        print_dberror();      // 打印錯(cuò)誤
        exec sql rollback release;  // 斷開(kāi)連接
        return 1;
}

游標(biāo)

游標(biāo)是什么? 我們?yōu)槭裁葱枰?

檢索單行結(jié)果,可將結(jié)果直接傳送到宿主程序的變量中.例如:

exec sql select Sname, Sage into :vSname, :vSage from Student where Sname = :specName ;

檢索多行結(jié)果, 就需要使用游標(biāo)(Cursor)

  • 游標(biāo)是指向某檢索記錄集的指針
  • 通過(guò)這個(gè)指針的移動(dòng), 每次讀一行處理一行, 再讀一行...., 直到處理完畢
  • 讀一行通過(guò)Fetch...into語(yǔ)句實(shí)現(xiàn), 每次Fetch, 都是向下移動(dòng)指針, 然后再讀取
  • 記錄集有結(jié)束標(biāo)識(shí)EOF, 用來(lái)標(biāo)記后面已沒(méi)有記錄了
游標(biāo)

游標(biāo)的使用:
游標(biāo)(Cursor)的使用需要先定義、再打開(kāi)(執(zhí)行)、接著一條接一條處理,最后再關(guān)閉. 可以定義一次, 多次打開(kāi).

exec sql declare cur_student cursor for
    select Sno, Sname, Sclass from Student where Sclass='035101' ;
exec sql open cur_student;
exec sql fetch cur_student into :vSno, :vSname, :vSclass;
… …
exec sql close cur_student;

可滾動(dòng)的游標(biāo)

標(biāo)準(zhǔn)的游標(biāo)總是從上往下的讀的. 但是我們想向上向下滾動(dòng)讀取. ODBC(Open DataBase Connectivity)是一種跨DBMS的DB操作平臺(tái), 它在應(yīng)用程序與實(shí)際的DBMS之間提供了一種通用接口, 可以幫助我們實(shí)現(xiàn)滾動(dòng)游標(biāo).

數(shù)據(jù)庫(kù)記錄的刪除與更新

刪除

查找刪除:

exec sql delete from customers c where c.city = 'Harbin' and
not exists ( select * from orders o where o.cid = c.cid);

定位刪除:

exec sql declare delcust cursor for
    select cid from customers c where c.city =‘harbin’ and
        not exists ( select * from orders o where o.cid = c.cid)
     for update of cid;
exec sql open delcust
While (TRUE) {
    exec sql fetch delcust into :cust_id;
    exec sql delete from customers where current of delcust ; 
}
更新

一種是查找更新, 一種是定位更新
查找更新:

exec sql update student s set sclass = "035102"
    where s.sclass = "034101"

定位更新:

exec sql declare stud cursor for
    select * from student s where s.sclass ="034101"
    for update of sclass;
exec sql open stud
    While (TRUE) {
        exec sql fetch stud into :vSno, :vSname, :vSclass;
        exec sql update student set sclass = "035102" where current of stud ; 
    }

數(shù)據(jù)庫(kù)插入

exec sql insert into student ( sno, sname, sclass)
    values ('03510128', '張三', '035101') ;

狀態(tài)捕獲及其處理

狀態(tài), 是嵌入式SQL語(yǔ)句的執(zhí)行狀態(tài), 尤其指一些出錯(cuò)狀態(tài), 有時(shí)程序需要知道這些狀態(tài)并對(duì)這些狀態(tài)進(jìn)行處理.
嵌入式SQL程序中, 狀態(tài)捕獲及處理有三部分構(gòu)成:

  • 設(shè)置SQL通信區(qū): 一般在嵌入式SQL程序的開(kāi)始處便設(shè)置
    exec sql include sqlca;
  • 設(shè)置狀態(tài)捕獲語(yǔ)句: 在嵌入式SQL程序的任何位置都可以設(shè)置, 可以多次設(shè)置, 但是有作用域
    exec sql whenever sqlerror goto report_error;
  • 狀態(tài)處理語(yǔ)句: 某一段程序以應(yīng)對(duì)SQL的某種狀態(tài)
    report_error: exec sql rollback;

SQL通信區(qū): SQLCA

  • SQLCA是一個(gè)已被聲明過(guò)的具C語(yǔ)言的結(jié)構(gòu)形式的內(nèi)存信息區(qū),其中的成員變量用來(lái)記錄SQL語(yǔ)句執(zhí)行的狀態(tài),便于宿主程序讀取與處理
  • SQLCA是DBMS(執(zhí)行SQL語(yǔ)句)與宿主程序之間交流的橋梁之一


狀態(tài)捕獲語(yǔ)句

exec sql whenever condition action;
Whenever語(yǔ)句的作用是設(shè)置一個(gè)"條件陷阱", 當(dāng)滿足條件的時(shí)候, 就會(huì)執(zhí)行相應(yīng)的動(dòng)作.


條件(condition)與動(dòng)作(action)

作用范圍, 兩個(gè)whenever 之間, 否則直到程序結(jié)束.
注意:作用域是語(yǔ)句在程序中的位置,而不是控制流程(因是預(yù)編譯程序處理?xiàng)l件陷阱)

回顧



數(shù)據(jù)庫(kù)系統(tǒng)學(xué)習(xí)筆記

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常。 O...
    我想起個(gè)好名字閱讀 5,970評(píng)論 0 9
  • 1.1 基本結(jié)構(gòu) PL/SQL程序由三個(gè)塊組成,即聲明部分、執(zhí)行部分、異常處理部分。 1.2 命名規(guī)則 1.3 記...
    慢清塵閱讀 4,069評(píng)論 3 14
  • 夜班,可以說(shuō)是每一個(gè)醫(yī)生和醫(yī)學(xué)生的標(biāo)配,每個(gè)人都逃不掉。 這當(dāng)然不是我上的第一個(gè)夜班,在鄭州上學(xué)期間,研二那一年我...
    邵兵125閱讀 1,130評(píng)論 12 5
  • Where You Are -- Young & FreeAnd after all this time with...
    Fetiz閱讀 257評(píng)論 3 0
  • 不知不覺(jué)工作已兩個(gè)月,但像是醉了酒似的,腦子一直處在暈暈的狀態(tài)。今夜,好不容易撐著眼皮閱讀了十幾分鐘,但那些詩(shī)意的...
    預(yù)感t閱讀 150評(píng)論 0 0

友情鏈接更多精彩內(nèi)容