狀態可以通過指示變量得到。
exec sql select 字段 into :宿主變量:指示變量
from 表 where 條件;
exec sql select 字段 into :宿主變量 indicator :指示變量
from 表 where 條件;
==0 正常
==-1 數據庫中的字段值是NULL值
>0 截斷賦值 儘量避免
#include <stdio.h>
exec sql include sqlca;
int main(){
exec sql begin declare section;
char userpasswd[30]="username/passwd";
char var_name[30];
int mid=-1;
/* 指示manager_id 賦值給mid */
short indmid=0;
exec sql end declare section;
exec sql connect:userpasswd;
exec sql select first_name,manager_id
into :var_name,:mid:indmid from s_emp
where id=2;
printf("var_name=%s\n",var_name);
printf("mid=%d,indmid=%hd\n",mid,indmid);
exec sql commit work release;
}
2. 數組變量:
(1)proc 只支持一維數組 ,字符除外
(2)proc 不支持數組指針
(3)最大元素數 32767
(4)數組變量在select語句中使用時 只能給出數組名 不能
給下標。
把s_emp 表中所有的first_name,commission_pct
分別放入兩個數組中 然後指示提成的賦值狀態
#include <stdio.h>
exec sql include sqlca;
int main(){
exec sql begin declare section;
char userpasswd[30]="username/passwd";
/* 定義兩個數組放名字和提成 */
char var_names[50][30];
double cpcts[50]={0};
/* 指示提成的數組 */
short indcpcts[50]={0};
exec sql end declare section;
exec sql connect:userpasswd;
exec sql select first_name,commission_pct
into :var_names,:cpcts:indcpcts
from s_emp;
/* 輸出數組中的數據 */
int i=0;
for(i=0;i<50;i++){
printf("%s:%lf:%hd\n",var_names[i],
cpcts[i],indcpcts[i]);
}
exec sql commit work release;
}
3. 可以從sqlca中獲得sql語句影響的行數據
sqlca通信區
sqlca.sqlerrd[2] sql語句影響的行數
sqlca.sqlcode sql語句執行狀態
==0 sql語句執行正常
>0 異常發生 一般是違反約束
<0 數據庫本身出錯 或者 網絡錯誤
sqlca.sqlerrm.sqlerrmc 得到sql執行出錯原因
exec sql update account set money=money-5000
where ano='A';
int a=sqlca.sqlcode;
exec sql update account set money=money+5000
where ano='B';
int b=sqlca.sqlcode;
if(a==0 && b==0){
commit;
}else{
rollback;
}
-----------------------------------------------
oraca 也是一個通信區 它是對sqlca的信息補充
資源消耗比較大 所有這個通信區默認關閉。
1.包含oraca
exec sql include oraca;
2.打開oraca通信區
exec oracle option(oraca=yes);
3.設置sql語句的保存狀態
oraca.orastxtf
0 默認的 不保存sql
1 sql出錯時保存
2 sql出現警告保存
3 無論什麼情況都保存
4.從oraca中得到sql文本
oraca.orastxt.orastxtc
#include <stdio.h>
exec sql include sqlca;
exec sql include oraca;
exec oracle option(oraca=yes);
int main(){
oraca.orastxtf=3;
exec sql begin declare section;
char userpasswd[30]="openlab/open123";
char var_name[30];
int var_id=10;
exec sql end declare section;
exec sql connect:userpasswd;
exec sql select first_name into :var_name
from s_emp where id=:var_id;
printf("%s\n",oraca.orastxt.orastxtc);
exec sql commit work release;
}
--------------------------------------
4. 數據庫的連接
本地連接:
exec sql connect:userpasswd;
exec sql connect:username
identified by :password;
遠程連接:
a.相關的文件
$ORACLE_HOME/network/admin/tnsnames.ora
當有多個數據庫連接時 需要使用at 來區分不同連接
這種數據庫連接 要使用$ORACLE_HOME/network/admin/
tnsnames.ora 中的數據庫描述。 在proc中需要使用關鍵字
using使用這個描述。但有多個數據庫連接時,要使用貼
標籤的方式來區分這些具體的連接。在以後的每個sql
操作前都使用 at 關鍵字指定連接。
#include <stdio.h>
exec sql include sqlca;
int main(){
exec sql begin declare section;
char userpasswd[30]="username/passwd";
/* 這是保存遠程數據庫數據的變量 */
char var_name[30];
/* 遠程數據庫描述 */
char rdbdes[20]="CAH_192.168.0.26";
exec sql end declare section;
/* 直接和rdbdes對應的遠程數據庫 建立連接*/
exec sql connect:userpasswd using :rdbdes;
/* 這是從192.168.0.26主機上取得數據 */
exec sql select first_name into :var_name
from s_emp where id=1;
printf("var_name=%s\n",var_name);
exec sql commit work release;
}
多個數據庫連接#include <stdio.h>
exec sql include sqlca;
int main(){
exec sql begin declare section;
char userpasswd[30]="username/passwd";
/* 這是保存遠程數據庫數據的變量 */
char var_name[30];
/* 遠程數據庫描述 */
char rdbdes[20]="CAH_192.168.0.26";
/* 製造標籤 */
char db23[20]="db23";
char db26[20]="db26";
exec sql end declare section;
/* 直接和rdbdes對應的遠程數據庫 建立連接*/
exec sql connect:userpasswd at :db26 using :rdbdes;
exec sql connect:userpasswd at :db23;
/* 這是從192.168.0.26主機上取得數據 */
exec sql at:db26 select first_name into :var_name
from s_emp where id=1;
printf("db26 var_name=%s\n",var_name);
/* 要從23數據庫連接上取得數據 */
exec sql at:db23 select first_name into :var_name
from s_emp where id=1;
printf("db23 var_name=%s\n",var_name);
exec sql at:db26 commit work release;
exec sql at:db23 commit work release;
}
b.使用數據庫鏈的方式
(1)建立鏈接
create database link 鏈接名 connect to 用戶名
identified by 密碼 using'(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.26)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ***)
)';
在192.168.0.26 的sqlplus中建立一個數據庫鏈接
叫my26link
create database link my26link connect to
username identified by passwd using
'(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.26)(PORT = 1524))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ***)
)';
叫my20link
create database link my20link connect to
openlab identified by open123 using
'(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.20)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ***)
)
)';
2.在proc中使用這些鏈接
exec sql select first_name into :var_name
from 表@鏈接名 where id=1;
exec sql update 表名@鏈接名 set
字段=值,字段=值 where 條件;
exec sql commit;
遠程數據庫事務 完全交給本地數據庫來控制
#include <stdio.h>
exec sql include sqlca;
/* 在本地數據庫中已經建立好了兩個
鏈接 db20link db26link */
int main(){
exec sql begin declare section;
char userpasswd[30]="openlab/open123";
char var_name[30];
exec sql end declare section;
/* 連接到本地數據庫 */
exec sql connect:userpasswd;
exec sql select first_name into :var_name
from s_emp where id=1;
printf("23db var_name=%s\n",var_name);
exec sql select first_name into :var_name
from s_emp@my20link where id=1;
printf("20db var_name=%s\n",var_name);
exec sql select first_name into :var_name
from s_emp@my26link where id=1;
printf("26db var_name=%s\n",var_name);
exec sql commit work release;
}