一.什么是pro程序
1.1通过在过程化编程语言中 嵌入sql语句开发出的应用程序
叫做pro程序。
1.2为什么要使用proc/c++
想使用c或者c++ 这种高效的语言 成为访问oracle数据库的
工具。
sql语句是嵌入在c 或者c++ 语言上
c 和 c++ 是宿主语言
二.proc 程序 和c 相同点和不同点
需要导入头文件 就导入头文件
需要定义函数 就定义函数
需要定义变量 就定义变量
不同点需要在操作数据库的操作前加 exec sql
包含一个和数据库操作相关的数据结构
exec sql include sqlca;
连接数据库
exec sql connect:usernameandpasswd;
查询数据
exec sql select first_name into :变量
from s_emp where id=1;
关闭数据库连接
exec sql commit work release;
exec sql rollback work release;
三.写一个c程序的步骤
3.1 编写源代码
vi ***.c
3.2 编译 链接
gcc ***.c -l库名
3.3 执行
./a.out
四.写一个proc程序的步骤
4.1 编写源代码
vi ***.pc
4.2 预编译 把pc文件变成c文件
proc ***.pc
4.3 编译链接
gcc ***.c -lclntsh
-lorasql10
4.4 执行
./a.out
ftp 192.168.0.26
openlab
open123
mkdir 文件夹
cd 文件夹
put 文件名 (上传文件)
get 文件名 (下载文件)
五.宿主变量
5.1 概念
使用宿主语言定义的变量。
即可以在宿主语言中使用,又可以在sql语句中使用。
5.2 宿主变量的类型
char
char var[n] 定长字符串
short
int
long
float
double
varchar var[n] 变长字符串
5.3 定长字符串 和 变长字符串
定长 char var[n];
变长 varchar var[n];
在select语句中 要和正常变量一样去使用
在宿主语言中 要使用.arr 取得数据
.len 存放的是数据的长度
5.4 使用proc的预编译选项 来处理字符串
gcc -c -E -S
proc char_map=charz 定长 空格补齐 \0结尾
=charf|varchar2 定长 空格补齐
=string 变长 \0结尾
5.5 宿主变量的使用注意事项
5.5.1 宿主变量 强烈建议放入申明区
exec sql begin declare section;
exec sql end declare section;
5.5.2 proc 中可以直接使用ddl
但ddl中不能使用宿主变量
char var_name[30]="s_emp";
exec sql drop table var_name;
5.5.3 可以使用指针 但必须分配内存
对字符串的动态内存分配支持的不好
不建议使用
5.5.4 宿主变量在sql语句中使用时 建议加上:
六. 指示变量
6.1 作用
当数据库中的字段值 赋值给宿主变量时 赋值的状态
可以通过指示变量得到。
==0 代表赋值正常
==-1 数据库中的字段值是NULL值
>0 代表截断赋值 尽量避免
6.2 语法
必须是short类型的变量
short indname=0;
short indsal=0;
exec sql select first_name,salary into
:var_name:indname,:var_sal indicator :indsal
from s_emp where id=1;
6.3 例子
把id=1 的 manager_id 赋值给一个宿主变量 赋值
的状态通过指示变量 得到。
七.数组变量
7.1 使用数组变量的注意事项
只支持一维数组 字符除外 char data[50][30];
不支持数组指针
最大元素个数 32767
使用数组时 在select语句中 只能出现数组的名字
不能出现数组的下标。
7.2 举例
把s_emp 表中所有的 first_name 和 manager_id
分别放入两个数组中 并且要指示manager_id 的
赋值状态。
八.sqlca通信区
exec sql include sqlca;
sqlca 实际上是一个结构体,在一个事务中 每执行一次
sql语句,就会把这个结构体中字段更新一遍。所以我们
要得到sql语句执行的信息 要立即获得 否则将下一条
sql覆盖掉。
sqlca.sqlerrd[2] 获得sql语句影响的行数
sqlca.sqlcode sql语句执行状态
==0 sql语句执行正常
>0 出现异常
<0 网络错误 或者数据库本身错误
sqlca.sqlerrm.sqlerrmc sql出错的原因
转账操作?
可以得到sql语句的状态
九. oraca 通信区(了解)
是对sqlca的信息补充。
根据设置的条件得到sql语句
9.1 包含oraca
exec sql include oraca;
9.2 打开oraca
exec oracle option(oraca=yes);
9.3 设置sql的保存标志
oraca.orastxtf
=0 默认的 不保存sql文本
=1 sql出错时保存
=2 sql 出现警告 或者出错时保存
=3 无论什么情况都保存
9.4 得到sql文本
oraca.orastxt.orastxtc
十. proc 中如何嵌入sql语句
10.1 如何嵌入select语句
在select 语句前加exec sql
结合into 把查询的内容放入宿主变量
10.2 如何嵌入 dml(insert delete update)
ddl(create drop alter)
tcl(commit rollback savepoint)
在这些语句前加exec sql
ddl 中不能使用宿主变量
使用proc 连接数据库 在程序中建立一张表
id number primary key
name varchar2(30) unique
并且判断建表是否成功
然后使用 insert 向表中放入一条数据
id 和name 的值来自于宿主变量
然后判断是否插入成功
再使用 update语句 把 id=1 的 name 更新成
'test'
使用查询语句把 id=1 name 查询出来 放入宿主变量
打印验证update的结果
一.proc 中如何嵌入plsql
1.1 proc程序中需要出现的代码
exec sql execute
begin
/* 这里相当于匿名块 */
end;
end-exec;
1.2 首先 写一个存储过程准备调用
设计一个存储过程 传入两个整数参数
把两个参数的和 存入第二个参数中。
create or replace procedure getsum(
x in number,y in out number)
is
begin
y:=x+y;
end;
1.3 预编译时
sqlcheck=semantics
userid=用户名/密码 是在预编译时连接数据库
确定存储过程是否存在和合法。
proc ***.pc sqlcheck=semantics
userid=openlab/open123
gcc ***.c -lclntsh
1.4 写一个函数 传入两个整数参数 返回两个参数的最大
值。使用proc程序调用 验证函数的功能
要求函数的参数 必须采用宿主变量传入。
create or replace function getmax(
x in number,y in number)return number
is
begin
if x<y then
return y;
end if;
return x;
end;
二.数据库的连接
2.1 本地数据库连接
exec sql connect:userpasswd;
exec sql connect:name identified by :password;
连接的数据库是 (数据库服务名)
echo $ORACLE_SID
2.2 远程数据库连接
$ORACLE_HOME/network/admin/tnsnames.ora
CAH_192.168.0.26 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.26)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = tarena)
)
2.3 使用远程数据库描述连接远程数据库
exec sql connect:userpassword at:标签名 using 远程数据库描述;
exec sql connect:userpasswd at:标签名;
只要在以后的每个操作前加上
exec sql at :标签名 即可
2.4 使用数据库链的方式 连接远程数据库
create database link my26link
connect to openlab identified by open123
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.26)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = tarena)
)';
select id,first_name from s_emp;
select id,first_name from s_emp@my26link;
select id,salary from
s_emp@my26link where id=15;
update s_emp@my26link set salary=salary+100
where id=15;
select id,salary from
s_emp@my26link where id=15;
远程数据库数据操作的事务 完全交给本地操作来控制。
a.根据语法建立数据库链接
b.在proc代码中使用数据库链接
在表名后 跟上@链接名
三.proc 中的错误处理
sqlca.sqlcode 用来判断sql语句的执行状态
sqlca.sqlerrm.sqlerrmc 当sql出错之后得到错误的
内容。
是局部处理 还是全局处理
exec sql whenever 条件 动作;
条件:sqlerror notfound sqlwarning
动作:do 错误处理函数();
do break; 用来终止循环
continue; 忽略错误继续处理
stop;
goto 标签;
proc 对sql错误的处理 采用的是忽略
四. 数据的操作
4.1 使用单个变量 一次操作单行单列
exec sql select first_name into :var_name
from s_emp where id=1;
4.2 使用多个变量 一次操作单行多列
exec sql select id,first_name,salary into
:id,:name,:salary from s_emp where id=2;
4.3 使用结构体到达多个变量的效果
4.4 多个数组操作 多行多列
4.5 游标操作多行多列
五. proc 中的游标操作
5.1 游标的使用步骤
声明游标
exec sql declare 游标名 cursor for select语句;
打开游标
exec sql open 游标名;
提取数据
exec sql fetch 游标名 into 宿主变量;
关闭游标
exec sql close 游标名;
5.2 举例
select id,first_name,salary from s_emp;
5.3 如何遍历游标中所有的数据
exec sql whenever notfound do break;
5.4 滚动游标(了解)
(可以不按照顺序提取游标中的数据)
scroll
fetch last 最后一条
first 第一条
prior 当前行的前一条
next 当前行的下一条
current 当前
relative n n是正数是向后
n是负数向前
absolute n 绝对的第几个
六 动态sql
把字符串 对应的sql语句当真正的sql来执行
6.1 不能是select
不能有占位符
exec sql execute immediate :sqlstr;
6.2 可以有占位符
不能是select
exec sql prepare s from :sqlstr;
exec sql execute s using 宿主变量。
6.3 只能是select语句
可以有占位符
"select id,first_name,salary from s_emp where id>:b0"
动态sql2 和 游标的结合
------------------------------------------------------
触发器
进行dml 操作时 系统可以做出相应的动作。
create table testemp9526 as select id, first_name,salary from s_emp;
create or replace trigger testemp9526_tri
before update on testemp9526
declare
begin
dbms_output.put_line('update testemp9526');
end;
update testemp9526 set salary=salary+100 where id=1;
update testemp9526 set salary=salary+100 where id<1;
update testemp9526 set salary=salary+100 where id>1;
语句级触发器 无论sql语句影响多少行 触发器只触发 一次。
行级触发器:sql 语句影响多少行 就触发多少次
create or replace trigger testemp9526_tri
before update on testemp9526 for each row
declare
begin
dbms_output.put_line(:old.id||':'||:old.salary);
dbms_output.put_line('update testemp9526');
dbms_output.put_line(:new.id||':'||:new.salary);
end;
update :old :new
delete :old
insert :new
触发器中 不能出现事务控制语句
事务谁发起 谁结束。
初学者Oracle数据库:Proc和Proc++的使用和示例
最新推荐文章于 2024-07-24 23:54:57 发布