oracle08proc

来源:互联网 发布:会员充值软件 编辑:程序博客网 时间:2024/06/03 17:26
 

2.嵌入plsql语句块 。写一个存储过程和函数,在proc程序中调用
create or replace procedure hellon(par_id number)
is
begin
 for abc in 1..par_id loop
  dbms_output.put_line('hello');
  end loop;
end;
-----------------------------------
create or replace function getmax(par1 number,par2 number) return number
is
begin
 if par1>par2 then
  return par1;
 end if;
 return par2;
end;
-------------------------------------
set serveroutput on

3.语法:
 exec sql execute
  begin
   /*语句块*/
  end;
 end-exec;

--------------------------------------
proc test.pc 会报错PCC-S-02345,只要调用语句块,必须给sqlcheck=semantics
proc test.pc sqlcheck=semantics
还是不可以:
注意:如果调用语句块选项,就要跟一个选项:userid
 proc test.pc sqlcheck=semantics userid=openlab/open123
sqlcheck:按照semantics的标准去检查语法。
userid:按照userid给定的用户名密码去检查调用的存储过程和函数存不存在。你必须指定用户名和密码去,调东西,因为有可能这个不是你自己的数据库。所以给用户名

******
proc tset.pc sqlcheck=semantics userid=openlab/open123 //需要调用sql语句块的编译方式
gcc test.c -lclntsh
******
find / -name *laji* 2>/dev/null


写proc程序测试
#include <stdio.h>
exec sql include sqlca;
int main(){
 exec sql begin declare section;
  char* userpwd;
  int res;
 exec sql end declare section;
 userpwd=malloc(30);
 strcpy(userpwd,"openlab/open123");
 exec sql connect:userpwd;
 if(sqlca.sqlcode==0){
  printf("connect success ! \n");
 }
 exec sql select first_name into:userpwd from s_emp where id=1;
 printf("%s \n",userpwd);
 exec sql execute
 begin
  hellon(10);
  :res:=getmax(10,100);/*这里用plsql的语法,变量用:,赋值用:=*/
 end;
 end-exec;
 printf("getmax: %d \n",res);
 exec sql commit work release;
}

--------------------------------------------------
sqlpluse :登录 system  open123 mydbku
 
 创建数据库:database configuration assistant 建立数据库了,之后别退出,需要点击:口令
管理。继续修改
报TNS错需要启动OraclejobschedulerDBPROC服务。 报listener:OraclehomeTNSListener服务
英文环境到中文环境的脚本:日期格式不对,会报错。@路径+文件名
 改语言环境变量配置:我的电脑--高级--环境变量--新建变量
  名:NLS_LANG
  值:AMERICAN_AMERICA.ZHS16GBK

window下写proc的开发;
 1即使是c开发要求,宿主变量必须在声明区。
 2连接库的名字是orsql10:不同的版本不一样
 3安装gcc or g++编译器 devcpp   :环境变量 c/xxx/devcpp/bin;
 
1.proc sqlerror.pc
2.gcc sqlerr.c -lorasql10 -L路径

----clear cls clear screen----------------------------------------------
数据库连接:
  本地连接的2种:1名和密码分开写 2名和密码一起写
   1 exec sql connect:username identified by :userpwd;
   2 exec sql connect:usernam_pwd;
    
  远程连接的方式:
   方式1:
   通过数据库连接 database link
   在sqlplus中创建数据库连接:
     create database link mylink connect to openlab identified by open123 using
     '查下面这个模板的写法';
   $ORACLEHOME/network/admin/tnsnames.ora中有远程连接模板例子。

 select salary from s_emp@mylink; //访问远程数据库的表和数据。
 
数据库的实例名:
 echo $ORACLE_SID
 方式2:上面的写法可以简化,需要本地装有数据库。
create database link mylink connect to openlab identified by open123 using 'DB26'
DB26配置在那个文件中../admin/tnsnames.ora ,使用using 关键字。

drop database link mylink;//删除连接。

2。观察上面的2种方式: 前提 必须登录数据库才能使用link
能不能直接连接别的数据库呢?前提本地装有数据库。
核心在于:$oracle_home/network/admin/tnsnames.ora

=========================================
上午讲得:
using 区分不同的数据库,可能是本地也可能是远程。
at 区分不同的数据库连接

sqlca与错误处理:
我们通过sqlca进行错误诊断和事务处理。
错误处理需要使用 whenever 条件 动作
条件:2个sqlerror  notfound(查询 或者 dml没有数据被操作)
动作:5个
 continue:出现sqlerror继续执行
 do :执行,可能是break 也可能是一个错误处理函数
 goto :执行嗯
 stop :停止,一般用不着。
 break;中断,和do联合使用,一般用于循环中,别的地方用还不性
例子:
#include <stdio.h>
exec sql include sqlca;/*这句话一定要写在下面这个函数的上面*/
void processnotfound();
int main(){
 exec sql whenever not found do processnotfound();
 exec sql begin declare section;
  char userpwd[30]="openlab/open123";
  char var_name[30];
  typedef struct emp{/*这样的话呢,emp即是类型又是变量,这样就可以把struct省略掉用*/
   int pid;
   char name[30];
  }emp;
 exec sql end declare section;
 exec sql connect:userpwd;
 exec sql select first_name into :var_name from s_emp where id=-1;
 emp.pid=10;
 strcpy(emp.name,"openlab");
 exec sql insert into testemp values(:emp);/*这样就把东东都放入进去了,我去!*/
 exec sql commit work release;
 
}
void processnotfound(){
 exec sql whenever sqlerror continue;/*如果下面出错了,那么继续处理。以免不走了*/
 printf("%s \n",sqlca.sqlerrm.sqlerrmc);
}

例子:
exec sql whenever
如果使用多个whenever,只有相对应的最近的whenever.

rollback所有的操作,release资源。exec sql rollback work release

数据的存取与更新:
 
在porc中使用结构体具有严格的要求,一般结构体定义要在声明区
exec sql begin declare section;
 #include "mystruct.h" /*只能使用基本类型,不能使用拓展类型:如size_t off_t */
exec sql end declare section;

单个变量的操作
多个变量的操作::1,:2,:3
结构体和数组操作:values(:emp_record);  or into :emp_record ,这样会自动保存在其中的每个相对应的元素。

数组:好处:降低网络的开销,因为他是一次进行数据的提交。
注意:在select语句的where子句中使用数组!

-------proc -滚动游标,非滚动游标---------------------
1.声明游标
2。开打游标
3。提取数据
4。关闭游标

proc和plsql的基本相同。
1.声明游标
 exec sql declare emp_cursor cursor for select * from where id=10;
2。开打游标
 exec sql open emp_cursor;
3。提取数据
 exec sql fetch emp_cursor into 宿主变量;
4。关闭游标
 exec sql close emp_cursor;
-------------------------------------------
#include <stdio.h>
exec sql include sqlca;
int main(){
 exec sql begin declare section;
  char userpwd[30]="openlab/open123";
  int sal;
 exec sql end declare section;
 exec sql connect:userpwd;
 exec sql declare salcursor cursor for select salary from s_emp;
 exec sql open salcursor;
 exec sql fetch salcursor into :sal;
 printf("sal: %d \n",sal);
 exec sql close salcursor;
 exec sql commit work release;
}

for循环cursor:
 open xxx
 for(;;){
  exec sql whenever not found do break;
  exec sql fetch salcursor into :sal;
  printf("sal:%d \n",sal);
 }
 close xxx

2。proc的滚动游标:能不能随机的处理数据,而非一行一行的走。
 他只比非滚动游标定义的时候多了个:scroll 而已。
 1.定义时:
 exec sql declare salcursor scroll cursor for select * from s_emp;
 2。
 exec sql fetch first emp_cursor into:empnum,:name:salary;
 控制滚动游标:first next current relative n last absolute n
  第一行,最后一行,当前行的上一行,当前行的下一行,相对的第n行,绝对的第n行。

3。动态sql
 sql1. exec sql execute immediate :host_string host_string 字符串
例子:
#include <stdio.h>
exec sql include sqlca;
int main(){
 exec sql begin declare section;
  char userpwd[20]="openlab/open123";
  char sqlstr[200];
 exec sql end declare section;
 strcpy(sqlstr,"create table testtab(id number)");
 exec sql connect:userpwd;
 exec sql execute immediate:sqlstr;
 exec sql commit work release;
}

 sql1的缺点是死的:1非select语句 2不能包含宿主变量

 动态sql2:解决了动态sql1的缺点:有宿主变量和select
  使用prepare命令准备sql语句。
  1 exec sql prepare abc from :host_string;//这个是宿主变量。说明
  2 exec sql execute abc using:var1
  
strcpy(sqlstr,"insert into tab values(:v1,:v2)");
exec sql connect:userpwd;
exec sql prepares s from :sqlstr;
exec sql execute s using :par_id,:par_name;
exec sql commit;
exec sql commit work release;

 动态sql3:sql2+游标=3  他可以是一个查询语句的动态sql.
  1.exec sql prepare abc from:host_string 标识符
  2。使用declare定义游标
例子:
strcpy(sqlstr,"select salary from s_emp where id>:v1");
connxxx
exec sql prepare s from :sqlstr;
exec sql declare salcursor cursor for s;/*用游标来访问*/
exec sql open salcursor using :par_id;/*打开时候使用using*/
for(;;){
 exec sql whenever not found do break;
 exec sql fetch salcursor into :sal;
 printf("%d \n",sal);
}
xxx release;/*熟悉了想忘记都忘记不了。*/ 他是一个查询语句的动态sql.

-------------------------------------
dms 文档:通用数据挖掘(采集整合)系统
1。wtmpx 日志文件
2。需求说明:项目是作什么的。
3。概要设计:项目需要的数据结构。粗略的设计
4。详细设计:类的组成和结构等,比较详细了。

unix服务器出租:
 

原创粉丝点击