1. proc中如何使用plsql
1.1 使用plsql的语法
exec sql execute
begin
/* 相当于plsql的匿名块 */
end;
end-exec; 在预编译时,需要加如下两个选项:
sqlcheck = semantics
userid = 用户名/密码:在预编译时时,检查调用的过程、函数等子程序是否存在及合法 1.2 在proc中调用存储过程
1) 创建一个存储过程,传入两个参数,把两数之和存入第二个参数
create or replace procedure getsum_zsm_00(
var_a number,var_b in out number)
is
begin
var_b:=var_a + var_b;
end; 2) 在proc中调用存储过程 案例:callproc.pc
#include <stdio.h>
exec sql include sqlca;
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
int x = 1;
int y = 9526;
exec sql end declare section;
exec sql connect:userpasswd;
exec sql execute
begin
getsum_zsm_00(:x,:y);
end;
end-exec;
exec sql commit work release;
printf("%d\n",y);
return 0;
}


1.3 在proc中使用函数
1) 创建一个函数,传入两个数字,返回最大值
create or replace function getmax_zsm_00(
var_a number,var_b number) return number
is
begin
if var_a > var_b then
return var_a;
end if;
return var_b;
end; 2) 编写一个proc程序,调用该函数 案例:callfunc.pc
#include <stdio.h>
exec sql include sqlca;
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
int x = 1;
int y = 9526;
int max=0;
exec sql end declare section;
exec sql connect:userpasswd;
exec sql execute
begin
:max:=getmax_zsm_00(:x,:y);
end;
end-exec;
exec sql commit work release;
printf("%d\n",max);
return 0;
}

2. 连接数据库
2.1 本地数据库连接
exec sql connect:用户名/密码;
exec sql connect:用户名 identified by :密码;
2.2 远程连接数据库
需要提供一个远程连接的描述字符串,包括:ip地址、端口号、oracle数据库的服务ID(服务器名)
这个字符串有固定格式,程序员可以根据格式拼接字符串
a文件中,一般有远程连接的$ORACLE_HOME/network/admin/tnsnames.or描述字符串的配置
$ORACLE_HOME:环境变量,oracle的安装路径 ip地址是要访问的数据库所在的服务器的ip地址
端口号默认1521 有了远程数据库的描述字符串,使用using引入描述:
exec sql connect:用户名/密码 using :描述字符串; 案例:rdbconn.pc
#include <stdio.h>
exec sql include sqlca;
int main(void){
exec sql begin declare section;
char userpasswd[]="openlab/open123";
// char rdbdesc[] = "DB10";
char rdbdesc[] = "(DESCRIPTION ="
"(ADDRESS = (PROTOCOL = TCP)(HOST = 172.60.5.80)(PORT = 1521))"
"(CONNECT_DATA ="
"(SERVER = DEDICATED)"
"(SERVICE_NAME = orcl)"
")"
")";
char name[];
exec sql end declare section;
exec sql connect:userpasswd using :rdbdesc;
if(sqlca.sqlcode)
printf("%s\n",sqlca.sqlerrm.sqlerrmc);
exec sql select first_name into :name
from s_emp where id=1;
exec sql commit work release;
printf("%s\n",name);
return 0;
}


    如果面对的是多个数据库,可以他通过定义标签,然后使用标签区分访问的是哪个数据库。

    案例:mdbconn.pc
#include <stdio.h>
exec sql include sqlca;
int main(void)
{
exec sql begin declare section;
char userpasswd80[]="openlab/open123";
char userpasswd81[]="openlab/open123";
char rdbdesc[]="DB10";
char name80[];
char name81[];
char label80[]="80";
char label81[]="81";
exec sql end declare section;
exec sql connect:userpasswd81 at :label81;
exec sql connect:userpasswd80 at :label80 using :rdbdesc;
exec sql at :label80 select first_name into :name80
from s_emp where id=1;
exec sql at :label81 select first_name into :name81
from s_emp where id=1;
exec sql at :label80 commit work release;
exec sql at :label81 commit work release;
printf("172.60.5.80:%s\n",name80);
printf("172.60.5.81:%s\n",name81);
return 0;
}


3. proc中的错误处理
3.1 局部的错误处理方式
sqlca.sqlcode //错误码
sqlca.sqlerrm.sqlerrmc //错误信息
3.2 全局的错误处理方式
错误处理方案只写一次,出现匹配的类型的错误,自动查找错误处理方案并执行 exec sql whenever 条件 动作;
条件就是错误的方式,有三种:
sqlerror: sql语句错误
notfound: 没有找到数据
sqlwarning: sql语句出现警告(不常用)
动作就是错误处理方案,包括:
do 错误处理函数(): 条件发生后,调用错误处理函数
do break: 退出循环
continue: 继续
stop: 停止执行代码(不常用)
goto 标签: 跳转到标签处(不常用) 标签: < <标签名> > 3.3 举例:删除一张不存在的表
案例:sqlerror.pc
#include <stdio.h>
exec sql include sqlca;
void sqlerror()
{
printf("sqlerror:%s\n",sqlca.sqlerrm.sqlerrmc);
}
void notfound()
{
printf("notfound:%s\n",sqlca.sqlerrm.sqlerrmc);
}
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
char name[];
int id=100;
exec sql end declare section;
exec sql whenever sqlerror do sqlerror();
exec sql whenever notfound do notfound();
exec sql connect:userpasswd;
exec sql drop table tablename;
exec sql select first_name into :name from s_emp
where id=:id;
exec sql commit work release;
return 0;
}


      proc中默认对错误是忽略的(不提示、不中断)

      sql语句出现错误,会向上查找对应的全局处理语句,如果有,执行处理方案。如果没有,继续执行后面的代码。

4. proc中的数据处理
1) 单行单列的结果集 使用一个宿主变量解决
....
char name[];
.....
exec sql select first_name into :name from s_emp
where id=1;
.....
2) 单行多列的结果集 使用多个宿主变量 或 结构体变量 解决
exec sql select id,first_name,salary into :id,:name,:sal
from s_emp where id=1; 案例:selecta.pc
#include <stdio.h>
exec sql include sqlca;
struct emp{
int id;
char name[];
double sal;
};
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
struct emp e;
exec sql end declare section;
exec sql connect:userpasswd;
exec sql select id,first_name,salary into :e
from s_emp where id=1;
exec sql commit work release;
printf("%d %s %g\n",e.id,e.name,e.sal);
return 0;
}

3) 多行单列的结果集   使用一个数组解决
exec sql select first_name into :names from s_emp; 4) 多行多列的结果集 使用多个数组、结构体数组、游标解决
exec sql select id,name,region_id into :ids,:names,:rids
from s_dept;
练习:使用多个数组接收s_dept表中的全部信息,并循环输出。
添加必要的错误处理 案例:selectb.pc
#include <stdio.h>
exec sql include sqlca;
struct emp{
int id;
char name[];
double sal;
};
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
struct emp emps[];
exec sql end declare section;
exec sql connect:userpasswd;
exec sql select id,first_name,salary into :emps
from s_emp;
exec sql commit work release;
int i=0;
for(;i<sqlca.sqlerrd[];i++)
{
printf("%d %s %g\n",emps[i].id,emps[i].name,
emps[i].sal);
}
return 0;
}


      在proc中使用游标的步骤:
a.声明游标
exec sql declare 游标名 cursor for select语句;
b. 打开游标
exec sql open 游标名;
c. 提取数据
exec sql fetch 游标名 into :宿主变量;
d.关闭游标
exec sql close 游标名; 使用游标时,结束循环采用:
exec sql whenever notfound do break; 案例:selectc.pc
#include <stdio.h>
exec sql include sqlca;
struct emp{
int id;
char name[];
double sal;
};
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
struct emp e;
exec sql end declare section;
exec sql connect:userpasswd;
exec sql declare empcursor cursor for
select id,first_name,salary from s_emp;
exec sql open empcursor;
exec sql whenever notfound do break;
while(1)
{
exec sql fetch empcursor into :e;
printf("%d %s %g\n",e.id,e.name,e.sal);
}
exec sql close empcursor;
exec sql commit work release;
return 0;
}


      有一种特殊的游标,叫做滚动游标。滚动游标可以直接调到任何一行。在用法上和普通游标(顺序游标)的区别:
a. 声明时,滚动游标关键字是scroll cursor
exec sql declare 游标名 scroll cursor for select语句;
b. 提取数据时,滚动游标有多种方式:
fetch first 提取第一行
fetch last 提取最后一行
fetch next 提取下一行
fetch prior 提取上一行
fetch absolute n: 提取第n行
fetch relative n 提取从当前位置开始的第n行
fetch current 提取当前行 exec sql fetch first 游标名 into :宿主变量 案例:cp selectc.pc scrollcursor.pc
#include <stdio.h>
exec sql include sqlca;
struct emp{
int id;
char name[];
double sal;
};
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
struct emp e;
exec sql end declare section;
exec sql connect:userpasswd;
exec sql declare empcursor scroll cursor for
select id,first_name,salary from s_emp;
exec sql open empcursor;
exec sql fetch absolute 10 empcursor into :e;
printf("%d %s %g\n",e.id,e.name,e.sal);
exec sql fetch next empcursor into :e;
printf("%d %s %g\n",e.id,e.name,e.sal);
exec sql fetch relative -5 empcursor into :e;
printf("%d %s %g\n",e.id,e.name,e.sal);
exec sql fetch last empcursor into :e;
printf("%d %s %g\n",e.id,e.name,e.sal);
exec sql close empcursor;
exec sql commit work release;
return 0;
}

5.动态sql
sql在执行时,才由参数传入 1) 非select语句,没有占位符
char sqlstr[]="create table....";
exec sql execue immediate :sqlstr; 案例:dsqla.pc 2) 非select语句,有占位符
char sqlstr[]="insert into.....values(:b0,:b1...)";
exec sql prepare stmt from :sqlstr;
exec sql execute stmt using :宿主变量....; 案例:dsqlb.pc
#include <stdio.h>
#include <string.h>
exec sql include sqlca;
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
char sqlstr[];
int id=1001;
char name[]="Tarena";
exec sql end declare section;
exec sql connect:userpasswd;
strcpy(sqlstr,
"insert into testdsql_zsm_00 values(:b0,:b1)");
exec sql prepare s from :sqlstr;
exec sql execute s using :id,:name;
exec sql commit work release;
return 0;
}

3) select语句
char sqlstr[]="select .... from ... where id>:b0";
exec sql prepare stmt from :sqlstr;
exec sql delcare 游标名 cursor for stmt;
.... 案例:dsqlc.pc
#include <stdio.h>
#include <string.h>
exec sql include sqlca;
struct emp{
int id;
char name[];
double sal;
};
int main(void)
{
exec sql begin declare section;
char userpasswd[]="openlab/open123";
char sqlstr[];
struct emp e;
int id=10;
exec sql end declare section;
exec sql connect:userpasswd;
strcpy(sqlstr,
"select id,first_name,salary from s_emp where id>:b0");
exec sql prepare s from :sqlstr;
exec sql declare empcursor cursor for s;
exec sql open empcursor using :id;
exec sql whenever notfound do break;
while(1)
{
exec sql fetch empcursor into :e;
printf("%d %s %g\n",e.id,e.name,e.sal);
}
exec sql close empcursor;
exec sql commit work release;
return 0;
}

----------------------------------------------------------------------
总结:
1. sql
select
select..from
表达式
别名
null值: nvl
where子句
比较运算符
between and
in
like _ % escape '\'
is null
逻辑运算符:and or not
order by 子句
order by 排序标准 排序方式,排序标准 排序方式
group by子句
select后的字段必须是分组标准,或者是组函数
having子句
分组后的筛选
单行函数
to_date to_char
组函数 表连接
select 字段列表
from 表1,表2 where 关联条件 [and 筛选条件];
(+):oracle中外连接 select 字段列表
from 表1 {{left|right|full} [outer] | [inner]} join 表2
on 关联条件 [where 筛选条件]; 子查询
where
select
having
from ddl:
table
sequence
view
index dml
insert delete update tcl
ACID: 约束 分页 2. plsql
变量
数据类型: record、table、 ref cursor
表名.字段%type
表名%rowtype
流程控制
动态sql
游标
异常
有名块
过程
函数

触发器 3.proc
宿主变量
指示变量
数组变量
通信区
嵌入sql、plsql语句
连接数据库
错误处理
select结果集的处理
动态sql ---------------------------------------------------------------------

proc程序中使用PLSQL、Exception 、 动态SQL(day08)的更多相关文章

  1. 程序中使用事务来管理sql语句的执行,执行失败时,可以达到回滚的要求。

    1.设置使用事务的SQL执行语句 /// <summary> /// 使用有事务的SQL语句 /// </summary> /// <param name="s ...

  2. Mybatis中输入输出映射和动态Sql

    一.输入映射 我们通过配置parameterType的值来指定输入参数的类型,这些类型可以是简单数据类型.POJO.HashMap等数据类型 1.简单类型 2.POJO包装类型 ①这是单表查询的时候传 ...

  3. ORACLE中使用DBMS_SQL获取动态SQL执行结果中的列名和值

    1.获取动态SQL中的列名及类型 DECLARE l_curid INTEGER; l_cnt NUMBER; l_desctab dbms_sql.desc_tab; l_sqltext ); BE ...

  4. 在PL/SQL中使用游标、动态sql和绑定变量的小例子

    需求:查询并输出30号部门的雇员信息 方式一:使用 loop...fetch SET serveroutput ON; DECLARE CURSOR c_emp IS ; v_emp emp%rowt ...

  5. 零基础学习java------36---------xml,MyBatis,入门程序,CURD练习(#{}和${}区别,模糊查询,添加本地约束文件) 全局配置文件中常用属性 动态Sql(掌握)

    一. xml  1. 文档的声明 2. 文档的约束,规定了当前文件中有的标签(属性),并且规定了标签层级关系 其叫html文档而言,语法要求更严格,标签成对出现(不是的话会报错) 3. 作用:数据格式 ...

  6. PL/SQL开发中动态SQL的使用方法

    一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...

  7. mysql 存储过程中使用动态sql语句

    Mysql 5.0 以后,支持了动态sql语句,我们可以通过传递不同的参数得到我们想要的值 这里介绍两种在存储过程中的动态sql: set sql = (预处理的sql语句,可以是用concat拼接的 ...

  8. 15_动态SQL

    [UserMapper.xml]和之前的作对比 <mapper namespace="com.Higgin.Mybatis.mapper.UserMapper"> &l ...

  9. Java下拼接执行动态SQL语句(转)

    在实际业务中经常需要拼接动态SQL来完成复杂数据计算,网上各类技术论坛都有讨论,比如下面这些问题: http://bbs.csdn.net/topics/390876591 http://bbs.cs ...

随机推荐

  1. Android 开发 ContentProvider 获取歌曲列表和联系人的样例

    ContentProvider(内容提供者)是Android中的四大组件之中的一个. 主要用于对外共享数据.也就是通过ContentProvider把应用中的数据共享给其它应用訪问.其它应用能够通过C ...

  2. [Cypress] Test XHR Failure Conditions with Cypress

    Testing your application’s behavior when an XHR call results in an error can be difficult. The use o ...

  3. oc33--构造方法2

    // Person.h #import <Foundation/Foundation.h> @interface Person : NSObject @property int age; ...

  4. Git Stash方法

    命令:git stash1.使用git stash 保存当前的工作现场, 那么就可以切换到其他分支进行工作,或者在当前分支上完成其他紧急的工作,比如修订一个bug测试提交. 2.如果一个使用了一个gi ...

  5. How to use shared model by git in sql source control of red gate

    1.clone the git repository for datbase 2.open sql source control window and select the target databa ...

  6. 动态规划---状压dp2

    今天模拟,状压dp又没写出来...还是不会啊,所以今天搞一下这个状压dp.这里有一道状压dp的板子题: Corn FieldsCorn Fields 就是一道很简单的状压裸题,但是要每次用一个二进制数 ...

  7. 杂项:ESB接口

    ylbtech-杂项:ESB接口 ESB全称为Enterprise Service Bus,即企业服务总线.它是传统中间件技术与XML.Web服务等技术结合的产物.ESB提供了网络中最基本的连接中枢, ...

  8. Coursera Algorithms week2 基础排序 练习测验: Intersection of two sets

    题目原文: Given two arrays a[] and b[], each containing n distinct 2D points in the plane, design a subq ...

  9. GYM 100741A Queries(树状数组)

    A. Queries time limit per test 0.25 seconds memory limit per test 64 megabytes input standard input ...

  10. python-day01 pip 在线安装,标识符规则,注释,变量名,类型

    1.python第三方库安装: 在线安装:pip install 库名 pip install 库名 -i 国内源网站地址 离线安装:xxx.tar.gz/rar/zip 解压安装 2.标识符规则: ...