实际开发中的proc教程_第1页
实际开发中的proc教程_第2页
实际开发中的proc教程_第3页
实际开发中的proc教程_第4页
实际开发中的proc教程_第5页
已阅读5页,还剩72页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Tar naPROC/C+课程PROC/C+Points3. 宿主变量与指示变量4. 嵌入SQL语句5. 连接数据库6. 错误处理1. PROC简介7. 数据的存取更新操作8. 动态sql2. PROC程序的编写步骤Pro程序通过在过程化编程语言中嵌入SQL语句而开发出的应用程序称为Pro程序。在通用编程语言中使用的SQL称为嵌入式SQL在SQL标准中定义了多种语言的嵌入式SQL各个厂商对嵌入式SQL的具体实现不同宿主语言 Pro程序C/C+ Pro*C/C+FORTRAN Pro*FORTRANPASCAL Pro*PASCALCOBOL Pro*COBOLPL/I Pro*PL/IAda

2、Pro*AdaPro*C/C+程序在C/C+语言中嵌入SQL语句而开发出的应用程序称为Pro*C/C+程序。目的:使c/c+这种高效率语言成为访问数据库的工具。Pro*C程序实例#includeEXEC SQL BEGIN DECLARE SECTION;char username20;char password20;char last_name25;EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE sqlca;void sqlerror();main() EXEC SQL WHENEVER SQLERROR DO sqlerror(); strcpy

3、(username,tarena); strcpy(password, tarena); EXEC SQL CONNECT:username IDENTIFIED BY:password; EXEC SQL select LAST_NAME into :last_name from S_EMP where id=2; printf(nID=2,last_name=%sn , last_name);void sqlerror() EXEC SQL WHENEVER SQLERROR CONTINUE; printf(n- oracle error detected:n); printf(%.70

4、sn, sqlca.sqlerrm.sqlerrmc); EXEC SQL ROLLBACK WORK RELEASE; exit(1); Include 头文件 (c/c+ and pro*c/c+) 定义变量 定义函数 main 连结数据库: connectSQL 操作语句: EXEC SQL .;exception handler断开连结: EXEC SQL COMMIT / ROLLBACK WORK releasePROC程序结构一般应用程序(C)开发运行标准流程CodeCompileLinkExecuteSourceProgramObjectProgramExecutablePro

5、gram.c文件文件.o文件文件可执行文件可执行文件 % vi a_1.c a_2.c % gcc c a_1.c a_2.c % gcc -oa a_1.o a_2.o 一般应用程序(C)开发运行标准流程Pro*C程序开发运行流程.o.o文件文件可执行文件可执行文件CodeCompileLinkExecuteSourceProgramObjectProgramExecutableProgram. .pcpc文件文件PrecompileModified SourceProgram.c.c文件文件完成Pro*C源程序到纯C源程序的转换基本命令格式PROC INAME=filename Optio

6、nName1=value1OptionNameN=valueNPro*C预编译程序PROC常用预编译选项 INAME=path and filename (name of the input file)ONAME=path and filename (name of the output file)INCLUDE=path (头文件所在路径)-INCLUDE =路径名 或 INCLUDE =(路径名1,路径名2)PARSE=FULL | PARTIA | NONE (default FULL for C, Others for C+)CODE=ANSI_C | CPP (default ans

7、i_c)USERID=username/passwordPro*C程序开发运行流程#includeEXEC SQL BEGIN DECLARE SECTION;char user_passwd20;EXEC SQL END DECLARE SECTION;EXEC SQl include sqlca;main() EXEC SQL WHENEVER SQLERROR stop; strcpy(user_passwd,tarena/tarena); EXEC SQL CONNECT:user_passwd; printf(nConnected to ORACLE as user:%sn , us

8、er_passwd);Pro*C程序开发运行流程% vi a.pc% proc a.pc% gcc -o a a.c -lclntsh -Compare Pro*C and its C codePro*C+预编译程序1. Pre-compile:proc myf.pc oname=myf.cpp parse=none code=cpp2. Compile:g+ -omyfile myfile.cpp lclntsh3. Execute:myfile#include Using namespace std;EXEC SQL BEGIN DECLARE SECTION;char user_pass

9、wd20;EXEC SQL END DECLARE SECTION;EXEC SQl include sqlca;main() EXEC SQL WHENEVER SQLERROR stop; strcpy(user_passwd,tarena/tarena); EXEC SQL CONNECT:user_passwd; coutConnected to ORACLE as user “salary; cinemp_number;EXEC SQL update emp set sal=:salary where empno= :emp_number; 输出 - 将数据库的数据传递到应用程序中。

10、float v_salary;char v_job; EXEC SQL select sal,job INTO :v_salary, :v_job from emp where empno = 7788;coutv_salarytable_name;EXEC SQL DROP TABLE :table_name;指示变量指示变量(indicator variable) 短整型变量,用于处理数据库的NULL值,监督和管理与其相关联的宿主变量。 引用语法::host_variable INDICATOR :indicator_variableOR:host_variable:indicator_v

11、ariable指示变量的作用主要用在输出, 即当宿主变量用于接收数据库的返回数据时。通过在宿主变量后用指示变量, 检测是否返回了NULL。-1:数据库表列的值为NULL,指示变量相关联的输出宿主变量值不确定=0:Oracle将数据库表列值原封不动的赋给指示器变量相关联的输出宿主变量0: Oracle将数据库表列值截断后赋给指示器变量相关联的输出宿主变量,指示器变量值为该列值的原始长度指示变量例子EXEC SQL BEGIN DECLARE SECTION; int m_id; short ind_m_id;EXEC SQL END DECLARE SECTION;EXEC SQL SELECT

12、 manager_id INTO :m_id:ind_m_id FROM s_emp WHERE id=1;If(ind_m_id =-1) cout“emp_desc is NULL”endl;else cout m_id endl;数组变量 Pro*C只支持一维数组 Pro*C不支持数组指针 Pro*C所支持数组最大维数是32767,超出此限制将报错 示例EXEC SQL BEGIN DECLARE SECTION;int A100;char B100;char C10015; EXEC SQL END DECLARE SECTION;数组变量 在SQL语句中使用数组变量,只需给出:和变量

13、名称, 不要给下标。 示例EXEC SQL BEGIN DECLARE SECTION;int emp_number100;char emp_name10015;EXEC SQL END DECLARE SECTION; EXEC SQL SELECT number,name INTO :emp_number, :emp_name FROM emp;数组变量错误的例子:for(int i = 0;i 0 有一个异常发生 0 系统错误,可能来自网络,或数据库本身 sqlerrm. sqlerrml保存错误文本信息的长度 sqlerrm. sqlerrmc保存错误文本信息,最长为70个字符 sql

14、errp 系统保留 sqlerrd60,1,3,5系统保留2当前SQL指令处理的行数4保存相对位移,指出在什么地方出现语法错误通信区说明 (SQLCA) sqlwarn80指示是否设置了警告标志1指示是否将字符结果返回给宿主变量时,数据截短了3如果查询时,返回的列数和指定的宿主数组变量的维数不等时设置该位4UPDATE和DELETE时没有行被处理,设置改标志位5当EXEC SQL CREATE PROCEDURE|FUNCTION|PACKAGE|PACKAGE BODY失败时,设置该位2,6,7系统保留 sqlext8 系统保留int main()EXEC SQL INCLUDE sqlca

15、;EXEC SQL WHENEVER SQLERROR Do err_report(sqlca); void err_report( struct sqlca sqlca) if (sqlca.sqlcode 0) printf(n%d%snn,sqlca.sqlerrm.sqlerrml ,sqlca.sqlerrm.sqlerrmc); exit(1); SQLCA应用实例通信区说明 ( ORACA) 当需要更进一步的信息时,ORACA将帮助我们达成愿望,所以ORACA也可以看作时SQLCA的补充和辅助。通信区说明 ( ORACA)struct oraca /* text */ char

16、oracaid8; /* Reserved */ /* ub4 */ int oracabc; /* Reserved */ /* ub4 */ int oracchf; /* 0 if check cur cache consistncy*/ /* ub4 */ int oradbgf; /* 0 if do DEBUG mode checking */ /* ub4 */ int orahchf; /* 0 if do Heap consistency check */ /* ub4 */ int orastxtf; /* SQL stmt text flag */struct /* ub

17、2 */ unsigned short orastxtl; /* text */ char orastxtc70; orastxt; /* text of last SQL stmt */ struct /* ub2 */ unsigned short orasfnml; /* text */ char orasfnmc70; orasfnm; /* name of file containing SQL stmt */ /* ub4 */ int oraslnr; /* line nr-within-file of SQL stmt */ /* ub4 */ int orahoc; /* h

18、ighest max open OraCurs requested */ /* ub4 */ int oramoc; /* max open OraCursors required */ /* ub4 */ int oracoc; /* current OraCursors open */ /* ub4 */ int oranor; /* nr of OraCursor re-assignments */ /* ub4 */ int oranpr; /* nr of parses */ /* ub4 */ int oranex; /* nr of executes */ ;通信区说明 ( OR

19、ACA) oracaid8 标识一个ORACA通信区 oracabc用于保存ORACA通信区的长度 oradbgf调试标志,0关闭,1开启 oracchf如果oradbgf1,那oracchf遵循下列规则:0禁止光标缓冲一致性检查1进行光标缓冲一致性检查 orahchf如果oradbgf1,那oracchf遵循下列规则:0禁止堆缓冲一致性检查1进行堆缓冲一致性检查 orastxtf可以是以下各值:0不保存SQL文本1仅对SQLERROR保存SQL文本2仅对SQLERROR和SQLWARNING保存SQL文本3总是保存SQL文本通信区说明 ( ORACA) 要使用ORACA,那么就要显式的加载O

20、RACA结构到Pro*C程序中。可通过语句EXEC SQL INCLUDE oraca;EXEC ORACLE OPTION(ORACA=YES);实现。 嵌入SQL语句EXEC SQL INSERT dept( 1, 人事部人事部, 中鼎大厦中鼎大厦7层层 );EXEC SQL sql-statement;形式:形式:示例:示例: 单个SQL语句的嵌入语法嵌入事务控制语句事务控制语句Commit, rollback and savepoint.EXEC SQL commit;EXEC SQL commit work release;EXEC SQL rollback work release

21、;嵌入事务控制语句EXEC SQL SAVEPOINT savepoint_insert;for( i = 1; i 100; i+ ) getInput1( empName, &salary ); EXEC SQL WHENEVER SQLERROR GOTO insert_error; EXEC SQL INSERT INTO emp( ename, sal ) VALUES( :empName, :salary ); EXEC SQL SAVEPOINT savepoint_delete;for( i = 1; i 100; i+ ) getInput2( &deptNo ); EXEC

22、 SQL WHENEVER SQLERROR GOTO delete_error; EXEC SQL DELETE FROM emp WHERE deptno = :deptNo; delete_error: EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK TO SAVEPOINT savepoint_delete; insert_error: EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK TO SAVEPOINT savepoint_insert; 数据操作语句(DM

23、L) 语句列表 EXEC SQL Select .; EXEC SQL Insert .; EXEC SQL update .; EXEC SQL Delete .;嵌入DML语句数据定义语句(DDL): create, alter, dropExample:EXEC SQL CREAT TABLE t1(cola int);EXEC SQL DROP TABLE t1;EXEC SQL ALTER TABLE t1 add(faxno number); 对象名, 列名不能用宿主变量. 自动提交事务嵌入DDL语句嵌入PL/SQL语句 PL/SQL的嵌入语法/*/EXEC SQL EXECUTE

24、 BEGIN /* PL/SQL BLOCK */ END;END-EXEC;/*/形式:形式:嵌入PL/SQL的语法PL/SQL的嵌入匿名块(anonymous blocks)/*- begin PL/SQL block -*/ EXEC SQL EXECUTE BEGIN SELECT job, hiredate, sal INTO :job_title, :hire_date, :salary FROM emp WHERE empno = :emp_number; DELETE from emp where empno = :emp_number; END; END-EXEC; /*-

25、end PL/SQL block -*/ 调用PL/SQL语句PL/SQL的嵌入package,procedure,functionEXEC SQL EXECUTE BEGIN emp_action.raise_salary( :empNo, :increase ); END; END-EXEC; Create or replace package emp_action is procedure raise_salary( empNO number, increase number);End emp_action;PL/SQL程序程序:Pro*C程序程序: 先有连结, 后才能访问数据库. 连结

26、的方法:连结本地或远程数据库连结一个或多个数据库 连接数据库EXEC SQL CONNECT :user IDENTIFIED BY :pswd | :usr_psw AT dbname | :host_variable USING :connect_string ALTER AUTHORIZATION :newpswd ; Connect 语法形式连接本地数据库本地: 客户应用程序与oracle server 在同一台机器上. 方式一:用户名口令由两个独立变量存储Char userName20 = “scott”;Char userPwd20 = “tiger”;EXEC SQL CONNE

27、CT :userName IDENTIFIED BY :userPwd;Char uname_pwd40 = “scott/tiger”;EXEC SQL CONNECT :uname_pwd; 方式二:用户名口令由单个变量存储连接远端数据库 远端: 客户应用程序与oracle server 不在同一台机器上.char userPwd20 = “scott / tiger”;char dbString20 = “remoteDB”;EXEC SQL CONNECT : userPwd Using :dbString;remoteDB 是网络服务名是网络服务名, 在在 $ORACLE_HOME/

28、network/admin/tnsnames.ora文件中定义文件中定义.连接方式:连接方式:使用数据库链访问远端数据库Char name25 = “scott smith”;/* 修改本地修改本地数据库区数据库区*/EXEC SQL update emp set sal=:salary where ename=:name;/* 修改修改远端数据库区远端数据库区*/EXEC SQL update empmyLink set sal=:salary where ename=:name;EXEC SQL commit work release; CREATE DATABASE LINK myLin

29、k CONNECT TO tarena IDENTIFIED BY tarena Using tlab1;用用SQLPLUS创建数据库链接:创建数据库链接:连接多个数据库应用程序应用程序远端远端数据库数据库ORA1远端远端数据库数据库ORA2远端远端数据库数据库ORA3本地本地数据库数据库ORA0Net8一个程序同时连接多个数据库或者建立多个连接到同一个数据库连接多个数据库char user110 = scott / tiger ,db110 = ora1“, dbString120 = “oracle1”;char user210 = scott / tiger “, db210 = ora

30、2“, dbString220 = “oracle2”;/*/EXEC SQL CONNECT :user1 AT :db1 Using :dbString1;EXEC SQL CONNECT :user2 AT :db2 Using :dbString2;Char name25 = “scott smith”;/* 修改修改db1数据库区数据库区*/EXEC SQL AT :db1 update emp set sal=:salary where ename=:name;/* 修改修改db2数据库区数据库区*/EXEC SQL AT :db2 update emp set sal=:sala

31、ry where ename=:name;EXEC SQL AT :db1 commit work release; EXEC SQL AT :db2 commit work release;使用数据库链访问远端数据库应用程序应用程序 Net8远端远端数据库数据库ORA2远端远端数据库数据库ORA1数据库链是在本地数据库和远端数据库之间的一种指针数据库链是在本地数据库和远端数据库之间的一种指针. 使用它可以在不同数据使用它可以在不同数据库的库的SQL语句和事务之间建立关联关系。语句和事务之间建立关联关系。 SQLCA与错误处理 为了给用户和开发人员提供oracle error message,

32、 Oracle 建议使用SQL通讯区(SQLCA). SQLCA is a C struct, 纪录每个当前SQL语句的执行状态,以便进行错误诊断和事件处理。 #include OREXEC SQL INCLUDE SQLCA; SQLCA通讯区 SQLCA的信息结构struct sqlca char sqlcaid8;long sqlcabc;long sqlcode;struct unsigned short sqlerrml;charsqlerrmc70; sqlerrm;char sqlerrp8;long sqlerrd6;char sqlwarn8;char sqlext8;WHE

33、NEVER 语句 检测并处理sql语句错误。语法:EXEC SQL WHENEVER condition: SQLWARNING, SQLERROR, NOT FOUND.action: CONTINUE, DO, GOTO, STOP,BREAKExample: EXEC SQL WHENEVER SQLWARNING CONTINUE; EXEC SQL WHENEVER SQLERROR DO sqlerror( ); EXEC SQL WHENEVER NOT FOUND DO notfound( );WHENEVER 语句的管辖范围 自动检查所有后面的SQL statements.

34、一般放在Before first SQL statement. If using more than one WHENEVER, 只有最近的 WHENEVER起作用。一般的错误处理方法 用WHENEVER 检查sql语句错误 用SQLCA描述错误 Rollback 所有的操作,release 资源.错误处理实例.void sqlerror();Main()EXEC SQL WHENEVER SQLERROR DO sqlerror();EXEC SQL CONNECT:username IDENTIFIED BY:password;EXEC SQL update emp set comissi

35、on=200 where emp_no=2; .void sqlerror() EXEC SQL WHENEVER SQLERROR CONTINUE; cout n- oracle error detected: sqlca.sqlerrm.sqlerrmc; EXEC SQL ROLLBACK WORK RELEASE; exit(1); 用单个变量操作单行单列 用多个变量或结构(struct )操作单行多列 用 数组(array)或 游标(cursor) 操作多行多列 数据的存取更新操作用单个变量操作单行单列char ename35;int empno=20;EXEC SQL selec

36、t emp_name INTO :ename from emp where emp_no=:empno;cout“the name is “ ename;注意事项: 字符串长度定义 指示变量的运用char v_name31, char v_job21;float v_salary;int empno=20;EXEC SQL select emp_name,job,salaryINTO :v_name,:v_job,:v_salaryFROM emp WHERE emp_no=:empno;coutv_name v_jobv_salary;注意事项: 变量顺序与字段名一至用多个变量操作单行多列宿

37、主结构是指包含多个宿主变量的C语言结构,以此可简化单行多列操作。Structintno;charname10;intsalary;emp_record;输入:EXEC SQL INSERT INTO emp(empno,ename,sal) VALUES (:emp_record);输出: EXEC SQL SELECT empno,ename,sal INTO :emp_recordWHERE rownum=1;用结构(struct )操作单行多列注意事项: 可用结构pointer,但要分配空间。 结构成员的数据类型,顺序必须与SQL语句一至。 不能用嵌套的结构。 不能用C联合(UNION)

38、用结构(struct )操作单行多列目的: 降低网络开销,提高程序性能。 数组和 INSERT 语句:int num100; float salary100; char name10025;/* 在此为ARRAY赋值 */EXEC SQL INSERT INTO emp(empno,ename,sal) VALUES (:num, :name, :salary);用数组(array)操作多行多列用 数组(array)操作多行多列 数组和 UPDATE / DELETE 语句Char name100; float salary100;. /* 在此为ARRAY赋值 */EXEC SQL UPDA

39、TE EMP SET sal=:salary WHERE ename=:name;Char name100;. /* 在此为ARRAY赋值 */EXEC SQL DELETE FROM emp WHERE ename=:name;用 数组(array)操作多行多列 数组和 SELECT 语句Char name10025;EXEC SQL SELECT ename INTO :name FROM empWHERE dept_num=2;For(int j=0;jsqlca.sqlerrd2;j+) cout“Emp_name”namejendl;用 数组(array)操作多行多列注意事项: 只有

40、CHAR 和 VARCHAR 可为二维数组。 如数组INDEX不同,按最小操作。 在SELECT语句的WHERE子句中,不能用数组。 数组元素最大值:32767使用非滚动游标1。定义游标 EXEC SQL DECLARE emp_cursor CURSOR FOR select empno,ename,sal from emp where deptno=10; 2. 打开游标 EXEC SQL OPEN emp_cursor ; (Open cursor: put the select results into a memory place, and the cursor pointer po

41、ints to the first row data.)3. 提取游标 EXEC SQL FETCH emp_cursor INTO :empnum,:name:salary; /* 在此处理数据处理*/ (After fetch, cursor pointer moves down one line. Use loop for multiple rows)4. EXEC SQL CLOSE emp_cursor;使用非滚动游标范例int dept_number, emp_name; float commission;EXEC SQL DECLARE emp_cursor CURSOR FOR

42、 SELECT empname, comm FROM EMP WHERE deptno = :dept_number;EXEC SQL OPEN emp_cursor;for( ;) EXEC SQL WHENEVER NOT FOUND DO break;EXEC SQL FETCH emp_cursor INTO :emp_name, :commission;if(commission 1) coutemp_name“先生,请加油“; EXEC SQL CLOSE emp_cursor;使用滚动游标 1. 定义游标 EXEC SQL DECLARE emp_cursor SCROLL CU

43、RSOR FOR select empno,ename,sal from emp where deptno=10; 2. 打开游标 EXEC SQL OPEN emp_cursor ; 3. 提取游标 EXEC SQL FETCH FIRST emp_cursor INTO:empnum,:name:salary; options: PRIOR(当前行的前一行),NEXT(当前行的下一行), CURRENT(当前行),RELATIVE n (n为付/正,当前行的前/后n行) ,ABSOLUTE n (游标中的第n行), LAST。 4. EXEC SQL CLOSE emp_cursor; 动

44、态SQL动态SQL是指在运行pro*c/c+应用程序时,动态输入的SQL语句。目的:加强应用程序的功能和灵活性。比较静态SQL和动态SQL:静态SQL - 在编写应用程序时,使用EXEC SQL关键字直接嵌入的SQL语句;动态SQL - 在运行应用程序时,由用户动态输入的SQL语句。什么时候使用动态SQL语句 SQL语句的文本(命令,子句等)不确定 宿主变量个数不确定 宿主变量的数据类型不确定 引用的数据库对象(列,表等)不确定动态SQL1动态SQL1概述语法:EXEC SQL EXECUTE IMMEDIATE :host_stringhost_string 字符串char sqlstmt1

45、00;Gets(sqlstmt)/* user input from keybord: “CREATE TABLE student( sno INT, sname CHAR(15) )” */EXEC SQL EXECUTE IMMEDIATE :sqlstmt;动态SQL1仅适用于非仅适用于非select语句语句语句中不包含输入宿主变量语句中不包含输入宿主变量判断如下语句是否能用:判断如下语句是否能用:Delete from emp where empno=:a;Delete from emp where empno=7788;Select ename from emp where empno=7788;常用于仅执行一次的动态语句常用于仅执行一次的动态语句对重复执行多次的动态对重复执行多次的动态SQL语句,降低执行效率语句,降低执行效率动态SQL方法2动态SQL方法21。使用PREPARE命令准备SQL语句 EXEC SQL PREPARE statement_name FROM :host_string; statement_name: 标识符, host_string:含SQL语句的字符串2。使用EXECUTE命令执行SQL语句 EXEC SQL EXECUTE statement_name USING :host_v

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论