Proc C概述.docx_第1页
Proc C概述.docx_第2页
Proc C概述.docx_第3页
Proc C概述.docx_第4页
Proc C概述.docx_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

一 Pro*C程序概述:1什么是Pro*C程序在ORACLE数据库管理和系统中, 有三种访问数据库的方法;(1) 用SQL*Plus, 它有SQL命令以交互的应用程序访问数据库;(2) 用第四代语言应用开发工具开发的应用程序访问数据库,这些工具有SQL*Froms,QL*Reportwriter,SQL*Menu等;(3) 利用在第三代语言内嵌入的SQL语言或ORACLE库函数调用来访问。Pro*C就属于第三种开发工具之一, 它把过程化语言C和非过程化语言SQL最完善地结合起来, 具有完备的过程处理能力,又能完成任何数据库的处理品任务,使用户可以通过编程完成各种类型的报表。在Pro*C程序中可以嵌入SQL语言, 利用这些SQL语言可以完成动态地建立、修改和删除数据库中的表,也可以查询、插入、修改和删除数据库表中的行, 还可以实现事务的提交和回滚。在Pro*C程序中还可以嵌入PL/SQL块, 以改进应用程序的性能, 特别是在网络环境下,可以减少网络传输和处理的总开销。2Pro*C的程序结构图通俗来说,Pro*C程序实际是内嵌有SQL语句或PL/SQL块的C程序, 因此它的组成很类似C程序。 但因为它内嵌有SQL语句或PL/SQL块, 所以它还含有与之不同的成份。为了让大家对Pro*C有个感性的认识, 特将二者差别比较如下:C的全程变量说明C源程序 函数1:同函数K。函数2:同函数K。C的局部变量说明函数K可执行语句应用程序首部 C的外部变量说明外部说明段(ORACLE变量说明)通讯区说明Pro*C源程序函数1:同函数K。函数2:同函数K。C局部变量说明程序体 内部说明部分 内部说明段通讯区说明函数K C的可执行语句可执行语句SQL的可执行语句或PL/SQL块二Pro*C程序的组成结构每一个Pro*C程序都包括两部分:(1)应用程序首部;(2)应用程序体应用程序首部定义了ORACLE数据库的有关变量, 为在C语言中操纵ORACLE数据库做好了准备。应用程序体基本上由Pro*C的SQL语句调用组成。主要指查询SELECT、INSERT、UPDATE、DELETE等语句。应用程序的组成结构如图所示:EXEC SQL BEGIN DECLARE SECTION (SQL变量的定义)EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLLA;EXEC SQL CONNECT: IDENTIFIED BY: SQL 语句及游标的使用1. 应用程序首部应用程序的首部就是Pro*C的开始部分。它包括以下三部分:l C变量描述部分;l SQL变量描述部分(DECLARE部分);l SQL通信区。(1) .DECLARE部分(描述部分)描述部分说明程序的SQL变量, 定义部分以EXEC SQL BEGIN DECLARE SECTION ;开始和以 EXEC SQL END DECLARE SECTION ;结束的。它可以出现在程序的主部,也可出现在局部l SQL变量的说明和使用在说明段能为SQL变量指定的数据类型如表所示:数据类型 描述CHARCHAR(n)INT SHORT LONG FLOAT DOUBLE VARCHAR 单字符n个字符数组整数短整数单精度浮点数双精度浮点数变长字符串这些数据类型实际上就是C语言的数据类型, 其中VARCHAR中视为C数据类型的扩充。这在以后会谈到。SQL变量的使用应注意以下几点:l 必须在描述部分明确定义l 必须使用与其定义相同的大小写格式l 在SQL语句中使用时,必须在其之前加一个“:”(冒号),但在C语句中引用时不需加冒号。l 不能是SQL命令中的保留字。l 可以带指示变量。例如:EXEC SQL BEGIN DECLARE SECTIONS;VARCHAR programe30;Int porgsal, pempno;EXEC SQL END DECLARE SECTION;EXEC SQL SELECT ENAME , SALINTO: programe, : progsalFROM EMPWHERE EMPNO = : pempno;(2). 指示器变量的说明和引用指示变量实际上也是一类SQL变量,它被用来管理与其相关联的宿主变量(即在SQL语句中充 当输入或输出的变量)。每一个宿主变量都可定义一个指示器变量,主要用于处理空值(NULL)指示器变量的说明基本同一般SQL变量一样, 但必须定义成2字节的整型,如SHORT、INT。在SQL语句中引用时, 其前也应加“:”(冒号),而且必须附在其相关联的宿主变量之后,在C语句中,可独立使用。当指示器变量为-1时,表示空值。例如:EXEC SQL BEGIN DECLARE SECTION ;INT dept- number;SHORT ind num;CHAR emp name;EXEC SQL END DECLARE SECTION ;Scanf(“90d %s”, & dept- number , dept name );If (dept number =0)Ind num = -1;ElseInd num = 0;EXEC SQL INSERT INTO DEPT (DEPTNO, DNAME)VALUES(:dept number : ind- num , :dept name);其中ind num是dept number 的指示器变量。当输入的dept number 值是0时, 则向DEPT 表的DEPTNO列插入空值。(3).指针SQL变量的说明和使用指针SQL变量在引用前也必须在DECLARE 部分先说明。其说明格式同C语言。在SQL语句中引用时,指针名字前要加前缀“:”(冒号)而不加“*”(星号)。在C语句中用法如同C语言的指针变量。(4).数组SQL变更的说明和引用在SQL语句中引用数组时,只需写数组名(名字前加冒号), 不需写下标,在C语句中用法如同C语言的数组变量。使用数组可大大降低网络传输开销。如要向一表插入100行数据,如果没有数组,就要重复100次, 而引用后,只须执行一次insert语句、便可一次性插入。例如:EXEC SQL BEGIN DECLARE SECTION;Int emp_number100;Char emp_name10015;Float salary100,commission100;Int dept_number;EXEC SQL END DECLARE SECTION;.EXEC SQL SELECT EMPNO,ENAME,SAL,COMMINTO :emp_number,:emp_name,:salary,:commissionFROM EMPWHERE DEPTNO=:dept_number;在使用数组时,应注意以下几点;l 不支持指针数组l 只支持一维数组, 而 emp-name 10015视为一维字符串l 数组最大维数为32767l 在一条SQL语句中引用多个数组时,这些数组维数应相同l 在VALUES , SET, INTO 或WHERE子名中, 不允许把简单SQL变量与数组SQL变量混用l 不能在DELARE部分初始化数组例如:下面的引用是非法的EXEC SQL BEGIN DECLARE SECTION;Int dept num 3 = ;EXEC SQL END DECLARE SECTION ;EXEC SQL SELECT EMPNO, ENAME , SALINTO : emp num i , : emp name i , : salarg i FROM EMP(5) 伪类型VARCHAR的说明和引用VARCHAR变量在引用之前也必须在说明段说明, 说明时必须指出串的最大长度,如:EXEC SQL BEGIN DECLARE SECTION;Int book number;VARCHAR book name 50 ;EXEC SQL END DECLARE SECTION ;在预编绎时, book name 被翻译成C语言中的一个结构变量;Struct unsigned short len ;Unsigned chart arr 20 ; boo name由此看出, VARCHAR变量实际上是含长度成员和数组成员的结构变量。在SQL语句中引用时,应引用以冒号为前缀的结构名, 而不加下标,在C语句 中引用结构成员。VARCHAR变量在作输出变量时,由ORACLE自动设置, 在作为输入变量时,程序应先把字符串存入数组成员中, 其长度存入长度成员中,然后再在SQL语句中引用。例如:Main( ) .scanf(“90s, 90d, book name .arr, & book number );book name .len = strlen (book name .arr);EXEC SQL UPDATE BOOKSET BNAME = : book name ;BDESC = : book number ;(6) SQL通信区SQL 通信区是用下列语句描述的:EXEC SQL INCLUDE SQLCA;此部分提供了用户运行程序的成败记录和错误处理。SQLCA的组成SQLCA是一个结构类型的变量,它是ORACLE 和应用程序的一个接口。在执行 Pro*C程序时, ORACLE 把每一个嵌入SQL语句执行的状态信息存入SQLCA中, 根据这些信息,可判断SQL语句的执行是否成功,处理的行数,错误信息等,其组成如表所示:Struct sqlca char sqlcaid 8 ; -标识通讯区long sqlabc; - 通讯区的长度long sqlcode; -保留最近执行的SQL语句的状态码struct unsigned short sqlerrml; -信息文本长度sqlerrm;char sqlerrp 8 ;long sqlerrd 6 ;char sqlwarn 8 ;char sqlext 8 ;struct sqlca sqlca;其中, sqlcode在程序中最常用到,它保留了最近执行的SQL语句的状态码。程序员根据这些状态码做出相应的处理。这些状态码值如下:0: 表示该SQL语句被正确执行,没有发生错误和例外。0:ORACLE执行了该语句,但遇到一个例外(如没找到任何数据)。0:表示由于数据库、系统、网络或应用程序的错误,ORACLE未执行该SQL语句。当出现此类错误时,当前事务一般应回滚。2应用程序体在Pro*C程序中, 能把SQL语句和C语句自由地混合书写,并能在SQL语句中使用SQL变量,嵌入式SQL语句的书写文法是:l 以关键字EXEC SQL开始l 以C语言的语句终结符(分号)终结SQL语句的作用主要用于同数据库打交道。C语言程序用于控制,输入,输出和数据处理等。(1) 连接到ORACLE数据库在对数据库存取之前,必须先把程序与ORACLE数据库连接起来。即登录到ORACLE上。所连接命令应该是应用程序的第一个可执行命令。连接命令格式如下:EXEC SQL CONNECT: IDENTIFIED BY : 或EXEC SQL CONNECT: / 在使用上述两种格式进行登入时, 应当首先在说明段定义包含用户名和口令的SQL 变量,并在执行CONNECT之前设置它们,否则会造成登录失败。例如:EXEC SQL BEGIN DECLARE SECTION ;VARCHAR usename 20;VARCHAR password20;EXEC SQL END DECLARE.strcpy ( usename.arr, “CSOTT);usename.len = strlen (username.arr);strcpy (password.arr , “TIGER);password .len = strlen( password .arr);EXEC SQL WHENEVER SQLERROR GOTO SQLERR;EXEC SQL CONNECT :username INDNTIFIED BY : password;注意: 不能把用户名和口令直接编写到CONNECT语句中,或者把用引号()括起来的字母串在CONNECT 语句中, 如下面的语句是无效的。EXEC SQL CONNECT SCOTT INENTIFIED BY TIGER;EXEC SQL CONNECT SCOTT IDENTIFIED BY TIGER;(2). 插入、更新和删除在讲述SQL语言时已详细讲过, 这里就不举例说明了。(3). 数据库查询及游标的使用在PRO*C中, 查询可分为两种类型:l 返回单行或定行数的查询;l 返回多行的查询.此种查询要求使用游标来控制每一行或每一组(主变量用数组).1) 返回单行或定行数的查询在PRO*C中的查询SQL SELECT语句由以下几个子句组成:SELECTINTOFROMWHERECONNECT BYUNIONINTERSECTMINUSGROUP BYHAVINGORDER BY其中WHERE子句中的查询条件可以是一个属性或多个属性的集合,在执行是赋值的主变量也可放在WHERE子句中.WHERE子句中所用的主变量称为输入主变量。如:SELECT EMPNO, JOB, SALINTO:PNAME, :PJOB, :PSALFROM EMPWHERE EMPNO=:PEMPNO;若没有找到限定的行, 则SQLCA.SQLCODE返回”+1403”, 表明”没有找到”。INTO从句中的主变量叫输出主变量,它提供了查询时所需要的信息。在任何项送给主变量之前,都要求ORACLE把这些项转换成主变量的数据类型。对于数字是通过截断来完成的(如:9.23转换为9)。如果已确定查询只返回一行,那么就不必使用游标,只给SELECT语句增加一个INTO子句即可。在语义上INTO语句在FROM之前的查询中有多少个选择项就有多少个输出主变量。若在SELECT项中表达式的数目不等于INTO子句中主变量的数目,就把SQLCA.SQLWARN3置为”W”。2)多行查询及游标的使用如果查询返回多行或不知道返回多少行,使用带有ORACLE游标(CURSOR)的SELECT语句。游标是ORACLE和PRO*C存放查询结果的工作区域。一个游标(已命名的)与一条SELECT语句相关联。操作游标有由4条命令:(1)DECLARE CURSOR;(2)OPEN CURSOR;(3)FETCH;(4)CLOSE CURSOR。A. 定义游标一个游标必须首先定义, 才能使用它。语法为:EXEC SQL DECLARE 游标名CORSOR FORSELECT 列FROM 表例如:EXEC SQL DECLARE CSOR, CURSOR FOR转载网上的一篇文章支持一下。PROC是ORACLE数据库提供的编程接口之一,其应用十分的广泛,本文通过一个具体的例子,介绍PROC编程的一些经验及应注意的地方。例子程序:#include#include#include#include#includeEXEC SQL INCLUDE sqlca;/*RELEASE_CURSOR=YES 使PROC 在执行完后释放与嵌入SQL有关资源*/EXEC ORACLE OPTION (RELEASE_CURSOR = YES);EXEC SQL BEGIN DECLARE SECTION;varchar vc_user20;long al_empno=0;char ac_ename11=;char ac_hiredate20=;double af_sal=0;EXEC SQL VAR ac_ename IS STRING(11);EXEC SQL VAR ac_hiredate IS STRING(20);EXEC SQL END DECLARE SECTION;/*错误处理函数*/void sql_error(char *msg)printf(n%s,%ld,%sn, msg,sqlca.sqlcode,(char *)sqlca.sqlerrm.sqlerrmc);EXEC SQL ROLLBACK RELEASE;exit(-1);main()EXEC SQL WHENEVER SQLERROR DO sql_error(ORACLE ERROR: );/*连接数据库*/strcpy(vc_user.arr,scott/tigerDEMO);vc_user.len=16;exec sql connect :vc_user;EXEC SQL DECLARE cur_emp CURSOR FORSELECT EMPNO, ENAME,to_char(HIREDATE,yyyy/mm/dd hh24:mi:ss),SAL FROM EMP;EXEC SQL OPEN cur_emp;while(1)al_empno=0;strcpy(ac_ename,);strcpy(ac_hiredate,);af_sal=0;EXEC SQL FETCH cur_emp INTO :al_empno, :ac_ename:ename_ind, :ac_hiredate:hiredate_ind, :af_sal:sal_ind;if( sqlca.sqlcode = 1403)break;printf(empno=%ld,ename=%s,hiredate=%s,sal=%lfn,al_empno,ac_ename,ac_hiredate,af_sal);EXEC SQL CLOSE cur_emp;EXEC SQL ROLLBACK WORK RELEASE;1、宿主变量的声明在PROC中,在SQL语句中用到的变量称为宿主变量。他们应在EXEC SQL BEGIN DECLARE SECTION;与EXEC SQL EDN DECLARE SECTION;之间声明,如上面所示.在声明宿主变量时应注意以下几点:(1) 在数据库表中定义为VARCHAR2,VARCHAR,CHAR的字段,在PROC中可声明为CHAR,但长度应为它们在表中定义的长度加1,因为PROC中CHAR型变量用做结尾。如:ENAME在表中的定义为ename varchar2(10),在PROC中可定义为:EXEC SQL BEGIN DECLARE SECTION;char ename11;EXEC SQL END DECLARE SECTION;常见错误说明:如果插入的字符串长度大于10,如:EXEC SQL INSERT INTO EMP(ENAME) VALUES(12345678901);会出现以下错误:error:ORA-01480: STR 赋值变量缺少空后缀。如果定义为:EXEC SQL BEGIN DECLARE SECTION;char ename15;EXEC SQL END DECLARE SECTION;当插入的字符串长度大于10,小于15时,如:EXEC SQL INSERT INTO EMP(ENAME) VALUES(12345678901);会出现以下错误:error:ORA-01401: 插入的值对于列过大。当插入的字符串长度大于15,如:EXEC SQL INSERT INTO EMP(ENAME) VALUES(12345678901234);会出现以下错误:error:ORA-01401:STR 赋值变量缺少空后缀。(2) 从SQL语句中取字段的值到宿主变量中时,PROC不会自动给宿主变量去掉右空格。而是以在DECLARE SECTION 中定义的长度为准(与 表中定义的无关)不足补右空格.如果不注意这一点,在PROC中进行字符串操作时(如比较相等)会出错。如:EXEC SQL BEGIN DECLARE SECTION;char ename10;EXEC SQL END DECLARE SECTION;如果ENAME在表中的值为abc,则取出的值为abc ;可用语句EXEC SQL VAR重定义CHAR型变量。这样宿主变量会自动去掉右空格。如下:EXEC SQL BEGIN DECLARE SECTION;char ename11;EXEC SQL VAR ac_ename IS STRING(11);EXEC SQL END DECLARE SECTION;如果ENAME在表中的值为abc,则取出的值为abc;(3) 对浮点型的变量,为保证精度,最好是声明成DOUBLE型的.因为DOUBLE型的精度比FLOAT型高很多.(4) 整型可声明为LONG型(对较长的整型,而且所用的平台支持的话,如在SUN平台上,可声明为LONG LONG型).(5) DATE型的处理:DATE型一般声明为CHAR(20)。往表中插入DATE型数据时,一般用TO_DATE()函数进行类型转换,取出值时一般用TO_CHAR()函数进行类型转换.EXEC SQL select to_char(hiredate,yyyy/mm/dd hh24:mi:ss) into :ac_hire_date from EMP where empno=1234;EXEC SQL insert into EMP(EMPNO,HIREDATE) values(123,to_date(:ac_hiredate,yyyy/mm/dd hh24:mi:ss);2、宿主变量的作用范围如果宿主变量在所有的函数之外声明,则他们是全局变量。在使用之前要注意把变量的值初始化,宿主变量也可以在某个函数的内部定义。 这时他们是局部变量。一般都习惯把宿主变量声明为全局变量。3、数据库的连接与断开数据库的连接有以下两种方法:(1)strcpy(vc_user.arr,scott/tiger);vc_user.len=11;exec sql connect :vc_user;(2)strcpy(user,scott);strcpy(pass,tiger);exec sql connect :user identified by :pass;注意:在有些平台上两种都可以,在有些平台上只能用第一种方法.在PROC程序中,要记住用EXEC SQL ROLLBACK WORK RELEASE;断开与数据库的连接,并释放相关的数据库资源。4、PROC中的NULL值的处理如果某一字段取出的值是NULL,会报:sqlcode=-1405, sqlerr=ORA-01405: 读取的列值为 NULL并且相应的宿主变量的值不会被改变,为执行该SQL语句之前的值. 常用的处理NULL值的方法有:(1)采用指示器变量,此时不会有-1405错误,当必须是所以为NULL的字段都有相应的指示器变量,如果某一字段没有指示器变量,但取出的值为NULL值,则仍然会有-1405错误.当取出的值是NULL时,相应的指示器变量变量为-1,可根据指示器变量的值做响应的处理。(2)如果字段较多,可取字段到一个结构体中及与该结构体对应的指示器结构体中.如上面的例子中可定义结构体:struct str_emplong al_empno;char ac_ename;char ac_hiredate;double af_sal;struct str_emp_indlong al_empno;char ac_ename;char ac_hiredate;double af_sal;struct str_emp str_emp;strcut str_emp_ind str_emp_ind;在取之前可用memset(&str_emp,0,sizeof(str_emp).清空该结构体,这样如果是字符型的NULL,会为,整型的NULL会为0,浮点型的会为0.00。此时不会有-1405错误。(3)也可采用NVL()函数:举例如下:EXEC SQL DECLARE authors CURSOR FORSELECT EMPNO, NVL(ENAME,chr(0),nvl(to_char(HIREDATE,yyyy/mm/dd hh24:mi:ss),chr(0),NVL(SAL,0) FROM EMP;这样也不会有-1405错误不,当取出的值是NULL时,自动用NVL()中指定的值代替.CHR(0)也可直接用代替,如下:SELECT EMPNO, NVL(ENAME,),nvl(to_char(HIREDATE,yyyy/mm/dd hh24:mi:ss),),NVL(SAL,0) FROM EMP;5、PROC中的错误的处理所有的SQL语句都有可能出错.所以都要加以判断,但每个SQL语句后都加错误判断,太麻烦,可用一个函数如sql_error()来进行错误处理,方法:(1)定义ql_error()函数。(2)在开头加上EXEC SQL WHENEVER SQLERROR DO sql_error();这样当发生sqlca.sqlcode 0的错误如 sqlca.sqlcode =1403 是不会转到sql_error()中执行的.另外:在UNIX下,可以用OERR 来查找错误的描述。如: ora ORA -1405 查找错误号为-1405的描述.6、PROC中调用存储过程的方法要把存储过程放在EXEC SQL EXECUTE 和 END-EXEC;之间,如下所示:其中:al_empno,ac_ename 为输入参数,l_return,l_errno,c_errtext 为输出参数。al_empno=8888;strcpy(ac_ename,ABCD);EXEC SQL EXECUTEBEGINup_db_emp(:al_empno,:ac_ename,:l_return,:l_errno,:c_errtext);END;END-EXEC;if (l_return != 0)printf(调用UP_PB_EMP存储过程出错,errno=%ld,errtext=%sn,l_errno,c_errtext);7、PROC的命令行选项:PROC编译器有很多的命令行选项,在命令行下直接不带参数运行PROC,会列出所有的命令行选项来,并有说明。(1)储存过程:编译储存过程是要带上用户名及密码proc USERID=scott/tiger sqlcheck=SEMANTICS ireclen=512 iname=test.cpp(2)PARSE=NONE 对非SQL代码不进行语法分析,默认对非SQL代码也进行语法分析.在RED HAD6.3上的ORACLE8.1.5中用PROC时,会提示:/USR/INCLUDE/STDIO.H 及其他的.H文件中有错. 可把PARSE=NONE加上,就好了.8、注意加上:EXEC ORACLE OPTION (RELEASE_CURSOR = YES);RELEASE_CURSOR=YES 使PROC 在执行完后释放与嵌入SQL有关资源,保证在该PROC程序执行完后,ORACLE不会锁住数据库资源,如锁表等。如果在PROC中用到ORACA,还要在程序头加上:EXEC ORACLE OPTION (ORACA=YES);9、PROC中的类型转换一、在C语言中:(1)字符型到整型可用ATOI() ATOL(),SSCANF()(2)整型,浮点型到字符型,可用SPRINTF()(3)字符型到浮点型用ATOF()不行,最好用SSCANF(),举例如下:EXEC SQL BEGIN DECLARE SECTION;double d_demo;float f_demo;char ac_text20=222;EXEC SQL END DECLARE SECTION;(1)sscanf(ac_text, %f, &d_demo);printf(ac_text=%s,d_demo=%fn,ac_text,d_demo);(2)sscanf(ac_text, %lf, &d_demo);printf(ac_text=%s,d_demo=%fn,ac_text,d_demo);(3)sscanf(ac_text, %f, &d_demo);printf(ac_text=%s,d_demo=%lfn,ac_text,d_demo);(4)sscanf(ac_text, %lf, &d_demo);printf(ac_text=%s,d_demo=%lfn,ac_text,d_demo);printf(*n);(5)sscanf(ac_text, %f, &f_demo);printf(ac_text=%s,f_demo=%fn,ac_text,f_demo);(6)sscanf(ac_text, %lf, &f_demo);printf(ac_text=%s,f_demo=%fn,ac_text,f_demo);(7)sscanf(ac_text, %f, &f_demo);printf(ac_text=%s,f_demo=%lfn,ac_text,f_demo);(8)sscanf(ac_text, %lf, &f_demo);printf(ac_text=%s,f_demo=%lfn,ac_text,f_demo);输出的结果:ac_text=222.00,d_demo=0.000000ac_text=222.00,d_demo=222.000000ac_text=222.00,d_demo=222.000032ac_text=222.00,d_demo=222.000000*ac_text=222.00,f_demo=222.000000ac_text=222.00,f_demo=0.000000ac_text=222.00,f_demo=222.000000ac_text=222.00,f_demo=0.000000d_demo=atof(ac_text);printf(ac_text=%s,atof(ac_text)=%fn,ac_text,d_demo);d_demo=atof(ac_text);printf(ac_text=%s,atof(ac_text)=%lfn,ac_text,d_demo);f_demo=atof(ac_text);printf(ac_text=%s,atof(ac_text)=%fn,ac_text,f_demo);f_demo=atof(ac_text);printf(ac_text=%s,atof(ac_text)=%lfn,ac_text,f_demo);输出的结果:ac_text=222.00,atof(ac_text)=1243288.000000ac_text=222.00,atof(ac_text)=1243288.000000ac_text=222.00,atof(ac_text)=1243288.000000ac_text=222.00,atof(ac_text)=1243288.000000从上面的结果可见:DOUBLE型应采用sscanf(ac_app_capcity, %lf, &d_app); 打印用%lf,%f 都可以. (2),(4)正确FLOAT型应采用sscanf(ac_app_capcity, %f, &d_app); 打印用%lf,%f 都可以. (5),(7)正确采用ATOF()转换的结果都是错的,所以不要用它。二、写表或从表中取数据时:(1)字符型与整型之间可不用转换,采用默认方式。(2)字符型与浮点型之间可不用转换,采用默认方式。(3)日期型与字符型之间可用TO_CHAR(),TO_DATE()。10、PROC中的4种动态SQL简介(1)动态SQL1: 不能是查询(SELECT)语句,并且没有宿主变量.用法:拼一串动态SQL语句,并用EXECUTE IMMEDIATE执行,如:EXEC SQL EXECUTE IMMEDIATE CREATE TABLE dyn1 (col1 VARCHAR2(4);(2)动态SQL2: 不能是查询(SELECT)语句,并且输入的宿主变量数目是知道的,用法:拼一串动态SQL语句,用PREPARE,EXECUTE语句执行.strcpy(c_sql, DELETE FROM EMP WHERE EMPNO = :?);EXEC SQL PREPARE sql_stmt FROM :c_sql;EXEC SQL EXECUTE sql_stmt USING :emp_number;(3)动态SQL3: 用于创建动态查询, 并且要查询的字段及输入的宿主变量数目是知道的用法: 拼一串动态SQL语句,用PREPARE分析该语句,并要定义一个CURSOR进行取值如:如要查询的数据按一年12月放到12张表中。表名为user_fee_1mon, user_fee_2mon,.可采用动态SQL3来进行查询strcpy(c_sql,select c_user_id,c_user_name,to_char(t_date,yyyy/mm/dd hh:mi:ss),n_feen);strcat(c_sql,from USER_FEE_);strcat(c_sql,ac_mon);strcat(c_sql, n where c_user_id = :v1);EXEC SQL PREPARE s FROM :c_sql;EXEC SQL DECLARE cur_user_fee CURSOR FOR s;EXEC SQL OPEN cur_user_fee USING :ac_user_id;while(1)EXEC SQL FETCH cur_user_fee into :c_user_id,:c_user_name,:c_date,:n_fee);if (sqlca.sqlcode 0)/*FETCH CURSOR失败*/printf(fetch cursor cur_user_fee fail,sqlcode=%ld,sqlserr=%s,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);if( sqlca.sqlcode = SQLNOTFOUND)break;EXEC SQL CLOSE cur_user_fee;(4)动态SQL4:要处理的字段及输入的宿主变量数目和主变量的类型事先是不知道的,如:INSERT INTO EMP () VALUES ()是最复杂的动态SQL,很少用,在此不做介绍。11、SQLCA:SQL是ORACLE的一个结构体,它的域用于最近的一条SQL语句执行后的一些信息,如错误号,错误描述,警告,状态等。常用的域介绍如下:SQLCA.sqlcode:错误号,=0正确,=1403没取到数据SQLCA.sqlserrm.sqlerrmc:错误描述SQLCA.sqlerrd3:最近的一条SQL语句所处理的行数,如果该语句处理失败,则它的值是不定的,如果错误在一个CURSOR操作中发生,则它的值指已成功处理的行数.在DELETE,UPDATE中,它不包含因外键约束而删除,更新的那些行,DELETE FROM EMP WHERE DEPT=SALE;在表EMP中删除20行,但如果表EMP与表ADDRESS有外键约束,导致表ADDRESS也被删除20行,则SQLCA.sqlerrd3=20,而不是40。SELECT ENAME , JOB, SALFROM EMPWHERE DEPTNO=:DEPTNO;当赋给一个与查询相关联的游标CURSOR之后, 当SELECT查询EMP时可从数据库中返回多行,这些行就是CURSOR的一个活动区域。注意:1) 定义游标必须在对游标操作之前完成;2) PRO*C不能引用没有定义的游标;3) 游标定义后,其作用范围是整个程序。所以对一个程序来讲, 同时定义两个相同的游标是错误的。B. 打开游标打开游标的OPEN语句主要用来输入主变量的内容,这些主要是WHERE中使用的主变量。打开游标的语句是:EXEC SQL OPEN 游标名当打开游标后,可以从相关的查询中取出多于一行的结果。所有满足查询标准的行组成一集合,叫做游标活动集。通过取操作,活动集中的每一行或每一组是一个一个返回的,查询完成后, 游标就可关闭了。如图所示:定义游标:DECLARE开始查询:SELECT打开游标:OPEN从活动集取数据:FETCH查询完成关闭游标:CLOSE注意:1)游标处于活动集的第一行前面;2)若改变了输入主变量就必须重新打开游标。C. 取数据从活动集中取出一行或一组把结果送到输出主变量中的过程叫取数据。输出主变量的定义在取数据语句中。取数据的语句如下:EXEC SQL FETCH游标名INTO:主变量1,主变量2,FETCH的工作过程如图所示:如图所示的查询结果指满足查询条件的查询结果。使用FETCH应注意以下几点:l 游标必须先定义再打开。l 只有在游标打开之后才能取数据,即执行FETCH语句。l FETCH语句每执行一次,从当前行或当前组取数据一次,下一行或下一组向上移一次。游标每次所指的行或组都为当前行或当前组,而FETCH每次都是取游标所指定的行或组的数据。l 当游标活动集空之后,ORCLE返回一个SQLCA。SQLCA(=1403)。l 若希望此游标再操作, 必须先关闭再打开它。l 在C程序中可以开辟一个内存空间,来存放操作结果,这样就能利用开辟的空间来灵活操纵查询的结果。D关闭游标取完活动集中所有行后,必须关闭游标,以释放与该游标有关的资源。关闭游标的格式为:EXEC SQL CLOSE 游标名;例如:EXEC SQL CLOSE C1;ORACLE V5.0版支持SQL格式“CURRENT OF CURSOR”。这条语句将指向一个游标中最新取出的行, 以用于修改和删除操作。该语句必须有取操作之后使用,它等同存储一个ROWID,并使用它。(4)举例EXEC SQL DECLARE SALESPEOPLE CURSOR FORSELECT SSNO, NAME, SALARYFROM EMPLOYEEWHERE DNAME=Sales;EXEC SQL OPEN SALESPEOPLE;EXEC SQL FETCH SALESPEOPLEINTO :SS,:NAME,:SAL;EXEC SQL CLOSE SALESPEOPLE;(5)SQL嵌套的方法及应用嵌入SQL与交互式SQL在形式上有如下差别:1) 在SQL语句前增加前缀“EXEC SQL”, 这一小小的差别其目的是在于预编译时容易识别出来, 以便把每一条SQL作为一条高级语言来处理。2) 每一SQ

温馨提示

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

评论

0/150

提交评论