很多來自網絡,自己整理了一下。
☆
概念
利用高級語言的過程性結構來彌補SQL語言實現復雜應用方面的不足。
嵌入SQL的高級語言稱為主語言或宿主語言。
在混合編程中,SQL語句負責操作數據庫,高級語言語句負責控制程序流程。
預編譯方法:由DBMS的預處理程序對源程序掃描,識別出SQL語句,把它們轉換成主語言調用語句,以使主語言編譯器能識別它,最后由主語言編譯器將整個源程序編譯成目標碼。
☆
嵌入式SQL的一般形式
所有的嵌入式SQL語句都必須加前綴EXEC SQL
在C語言中: EXEC SQL <SQL語句>
例如:EXEC SQL DROP TABLE Student;
☆
嵌入式SQL與主語言的通信
向主語言傳遞SQL語句執行狀態信息,使語言能夠據此信息控制程序流程,用SQL通信區(SQLCA【SQL Communication Area】)實現。
主語言向SQL語句提供參數,主要用主變量(Host Variable)實現;
將SQL語句查詢數據庫的結果交主語言進一步處理,主要用主變量和游標(Cursor)實現。
☆
SQL通信區
SQLCA中有一個存放每次執行SQL語句后返回代碼的變量SQLCODE。
每次執行完SQL語句后都應該測試一下SQLCODE的值,以了解該SQL語句執行情況并做相應處理,如果SQLCODE等于預定的常量SUCCESS,則表示SQL語句成功,否則在SQLCODE中存放錯誤代碼。
SQLCA(SQL Communication Access) 系由系統提供之系統記錄架構,作為back end與 front end 之間溝通之用,當發生 I/O 狀態時,系統會記錄該狀態于SQLCA 中,front end 即可依據其其內容得知 I/O 運作是否成功,再決定往后執行的步驟。SQLCA 為系統定義之 GLOBAL變量,以下為其架構并介紹其內容與用途:
DEFINE SQLCA RECORD
SQLCODE INTEGER,
SQLERRM CHAR(71),
SQLERRP CHAR(8),
SQLERRD ARRAY[6] OF INTEGER,
SQLAWARN CHAR(8)
END RECORD
.SQLCODE :表示 I/O 的結果
0 表示 I/O 成功
100 表示 NOTFOUND
< 0 表示 I/O 失敗
.SQLERRM :保留未用
.SQLERRP :保留未用
.SQLERRD :為一個含有6個INTEGER數組
SQLERRD[1]:保留未用
SQLERRD[2]:新增時 SERIAL 字段所傳回之值
SQLERRD[3]:處理資料的筆數
SQLERRD[4]:查詢時預估的 CPU COST
SQLERRD[5]:SQL指令之錯誤位移
SQLERRD[6]:最后一個 ROWID 值
.SQLAWARN :為一個含有8個字符的字符串,以記錄I/O時產生的警告訊息。若正確無誤,則相對應之字符設定為空白,否則會被設定為"W"。
SQLAWARN[1]:若第2至第8字符中任意一個被設成"W",則此字符亦為"W",否則為空白。
SQLAWARN[2]:若資料太長而被截掉時,會被設成 "W"。
SQLAWARN[3]:若 aggregate function(如 SUM,AVG,MAX,MIN) 處理時遇到 NULL 值,則會被設成"W"。
SQLAWARN[4]:若查詢時,若欲查詢的字段數目和 INTO 之變量數目不合時,會被設成 "W"。
SQLAWARN[5]:如轉換 float 成 integer 時,則會被設成 "W"。
SQLAWARN[6]:保留未用
SQLAWARN[7]:保留未用
SQLAWARN[8]:保留未用
☆
主變量
一個主變量既可是輸入主變量也可是輸出主變量。
主變量必須在SQL語句EXEC SQL BEGIN DECLARE SECTION與EXEC SQL END DECLARE SECTION之間進行說明。
例如:
EXEC SQL BEGIN DECLARE SECTION;
int i=0;
EXEC SQL END DECLARE SECTION;
SQL語句的主變量名前要加冒號作為標志。
在SQL語句之外,主變量直接引用,不須加冒號。
☆
使用游標查詢
EXEC SQL DECLARE cur CURSOR FOR select name,sex from student where no like :no;//定義游標
EXEC SQL OPEN cur;//打開游標
for(;;){
EXEC SQL fetch cur into :name,:sex;//推進游標
if(sqlca.sqlcode==100)//沒有滿足條件的數據
break;
//操作數據
}
EXEC SQL close cur;//關閉游標
EXEC SQL free cur;//釋放游標
☆
使用事務
事務的三個常用操作:開始事務(BEGIN WORK),提交事務(COMMIT WORK),回滾(ROLLBACK WORK),
例如:
EXEC SQL BEGIN WORK;
……//數據庫操作
if(sqlca.sqlcode<0)
EXEC SQL ROLLBACK WORK;
else
EXEC SQL COMMIT WORK;
☆
CURRENT形式的UPDATE語句和DELETE語句
UPDATE和DELETE語句都是集合操作,如果只想修改或刪除其中的某個記錄,則需要用帶游標的SELECT語句查出所有滿足條件記錄,從中進一步找出要修改或刪除的記錄,然后用CURRENT形式的UPDATE和DELETE語句處理。
用DELCARE語句說明游標。如果是為CURRENT形式的UPDATE語句作準備,則SELECT語句中要用 FOR UPDATE OF<列名>用來指明查詢出的數據在指定列是可修改的。如果是為CURRENT形式的DELETE語句作準備,則不必使用上述子句。
檢查該記錄是否為該修改或刪除的記錄。如果是,則修改或刪除之。這時UPDATE和DELETE語句中要用子句 WHERE CURRENT OF<游標名>,表示修改或刪除的是最近一次取出的記錄,即游標指針指向的記錄。
例如:
char yn;
EXEC SQL BEGIN DELCARE SECTION;
char Sno[20],Sname[20],NEWSname[20];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur CURSOR FOR SELECT Sno, Sname FROM Student WHERE Sno like '01%' FOR UPDATE OF Sname;
EXEC SQL OPEN cur
while(1) { /*用循環結構逐條處理結果集中的記錄*/
EXEC SQL FETCH cur INTO :Sno,:Sname;
if(sqlca.sqlcode==100)
break; /*若查詢結果處理完或出現錯誤,則退出循環*/
printf("no=%s,name=%s",Sno,Sname);
printf("UPDATE Name(y/n)?"); /*問用戶是否需要修改*/
scanf("%c", &yn);
if(yn='y' or yn='Y') /*需要修改*/
{
printf("INPUT NEW Name:");
scanf("%d",&NEWSname);
EXEC SQL UPDATE Student SET Sname = :NEWSname WHERE CURRENT OF cur;
};
};
EXEC SQL CLOSE cur;
☆
數據類型
1、SQL與C數據類型的對應簡單類型
SQL C
CHAR(n) char(n+1)
CHARCTER(n) char *
SMALLINT short
INTERGER int
SMALLFLOAT float
FLOAT/DOUBLE double
SERIAL long int
DATE long int
VARCHAR string
2、數據類型轉換
轉換類型 轉換后
FLOAT DECIMAL(16)
SMALLFLOAT DECIMAL(8)
INTERGER DECIMAL(10,0)
SAMLLINT DECIMAL(5,0)
☆
有關CHAR類型的函數
1、以空值結尾的串的操作函數
rdownshift(char *s) 把一個字符串中的所有字母轉換成小寫形式。
rupshift(char *s) 把一個字符串中的所有字母轉換成大寫形式。
stcat(char *s, char *dest) 把一個字符串同另一個字符串相連接。
stcmpr(char *s1, char *s2) 比較兩個字符串。
stcopy(char *from, char *to) 把一個字符串拷貝到另一個字符串。
stleng(char *string) 統計字符串的長度。
2、定長串的操作函數
bycmpr(char byte1, byte2, rpt len) 比較兩組連續的字節內存塊。
bycopy(char *from, char *to, int len) 把一塊內存的內容拷貝到另一塊內存。
byfill(char *to, int len, char ch) 用字符填充指定的內存塊。
byleng(char from, int count) 統計有效字符的數目。有效字符是指字符串去除了末尾空格所剩的字符。
3、字符串操作函數
ldchar(char *from, int num, char *to) 拷貝定長串到空值結尾的串。
stchar(char *from, char *to, int num) 拷貝空值結尾的串到定長串。
4、字符串函數簡單數值轉換
rstod(char *str, double *dblval) 把以空值結束的字符串轉換成C的double型
rstoi(char *str, int *intval) 把以空值結束的字符串轉換成C的int類型。
rstol(char *str, long *lngval) 把以空值結束的字符串轉換成C的long類型。
☆
DATE類型的函數
1、創建內部日期
rdefmtdate(long *jdate, char *frmt char *str) 生成具有確定格式的日期字符串。(str字符串和fmt必須按月、日、年的同一順序)
返回代碼:0操作成功;-1204在str參數中有非法的月份;-1206在str參數中有非法的日期;-1209由于str中沒有包含年、月、日各部分間的定界符,str的長度必須準確定義為6或8個字節長;-1212fmt中沒有包含年、月、日部分。
fmt和str的有效組合
fmt str
"mmddyy" "DEC 25th 1997"
"mmm.dd.yyyy" "dec 25 1997"
"mmm.dd.yyyy" "DEC-25-1997"
"mmm.dd.yyyy" "12251997"
"mmm.dd.yyyy" "12/25/1997"
"yy/mm/dd" "97/12/25"
"yy/mm/dd" "1997,December, 25th"
"yy/mm/dd" "In the year 1997, the month of December, its 25th day"
"dd-mm-yy" "This 25th day of December, 1997"
rmdyjul(short mdy[3], long *jdate) 用三個短整數生成一個內部日期這三個整數是有關年、月、日的數字值。(年必須以完整的形式表達)
返回代碼:0操作成功。 -1204在mdy[2]中有非法年份。 -1205在mdy[1]中有非法月份。 -1206在mdy[0]中有非法日期。
rstrdate(char *str, long *jdate) 將一個字符串日期轉換成一內部格式的日期。
rtoday(long *jdate) 從系統日期創建一個內部日期值。
2、從內部日期轉換成其他類型
rfmtdate(ling jdate, char *fmt, char *str) 從內部格式的日期類型值創建格式化的字符串。返回代碼:0操作成功。 -1210內部日期不能被轉換成月-日-年格式。-1211程序存儲溢出,即存儲分配錯誤。
rjulmdy(long jdate, short mdy[3]) 從一個內部日期生成一個含有3個短整數的數組對應內部日期的月、日、年。
rdatestr(long jdate, char *str) 從一個內部日期值創建缺省的日期字符串。
rdayofweek(long jdate) 給定一內部格式表示的日期,此函數返回所對應的星期中的某一天。
rleapyear(int year) 用來判斷給定的年份是否為閏年。 返回值:TRUE(1)是閏年;FALSE(0)不是閏年
☆
簡單數值類型的格式化函數
rfmtdouble(double dbval, char *fmt, char *str) 將雙精度格式化為指定的模板格式。
rfmtlong(double longval, char *fmt, char *str) 將長整型值格式化為指定的模板格式。
可以構成格式模板串的字符:
*以星號代替空格。
&以0代替空格。
#代表一個數字或空格的位置。
<左調整,顯示一個逗號,僅當左邊有數字時才顯示。
.顯示一個小數點,一個格式模板串只能有一個小數點。
-顯示負號,當數字為負的時候顯示。
+顯示正號,當數字為正的時候顯示。
(顯示一個負號,同(一起顯示負值。
)顯示一個負號,同)一起顯示負值。
$顯示美元符號。
☆
處理空值的數值類型函數
risnull(int type, char *c) 檢查C變量是否為空值。
rsetnull(int type, char *c) 給C變量置空值。
☆
其他函數
typalign(int pos, int type) 返回一具有指定數據類型變量的下一個位置。
rtypmsize(int sqltype, int sqllen) 返回你必須分配在存儲單元中的指定的C或RDSQLD的字節數。
rtyname(int sqltype) 返回一包含指定RDSQL類型名的以空結尾的串。
rtypwidth(int sqltype, intsqllen) 返回一具有RDSQL類型的值轉換為一字符類型時避免截取所需的最小字符數。
posted on 2007-07-23 13:56
破繭而出 閱讀(3370)
評論(0) 編輯 收藏 所屬分類:
數據庫 、
C/C++