ORACLEtrain3.docx
《ORACLEtrain3.docx》由会员分享,可在线阅读,更多相关《ORACLEtrain3.docx(29页珍藏版)》请在冰豆网上搜索。
![ORACLEtrain3.docx](https://file1.bdocx.com/fileroot1/2023-7/27/6c9417d5-1dcc-4e53-ac2f-f836119651fd/6c9417d5-1dcc-4e53-ac2f-f836119651fd1.gif)
ORACLEtrain3
Pro*C的使用
一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块,以改进应用程序的性能,特别是在网络环境下,可以减少网络传输和处理的总开销。
2.Pro*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局部变量说明
程序体内部说明部分内部说明段
通讯区说明
函数KC的可执行语句
可执行语句SQL的可执行语句
或PL/SQL块
二.Pro*C程序的组成结构
每一个Pro*C程序都包括两部分:
(1)应用程序首部;
(2)应用程序体
应用程序首部定义了ORACLE数据库的有关变量,为在C语言中操纵ORACLE数据库做好了准备。
应用程序体基本上由Pro*C的SQL语句调用组成。
主要指查询SELECT、INSERT、UPDATE、DELETE等语句。
应用程序的组成结构如图所示:
应用程序首部
描述部分
SQL通信区
应用程序体
EXECSQLBEGINDECLARESECTION
(SQL变量的定义)
EXECSQLENDDECLARESECTION;
EXECSQLINCLUDESQLLA;
EXECSQLCONNECT:
<用户名>
IDENTIFIEDBY:
<口令>
SQL语句及游标的使用
1.应用程序首部
应用程序的首部就是Pro*C的开始部分。
它包括以下三部分:
●C变量描述部分;
●SQL变量描述部分(DECLARE部分);
●SQL通信区。
(1).DECLARE部分(描述部分)
描述部分说明程序的SQL变量,定义部分以EXECSQLBEGINDECLARESECTION;开始和以EXECSQLENDDECLARESECTION;结束的。
它可以出现在程序的主部,也可出现在局部
●SQL变量的说明和使用
在说明段能为SQL变量指定的数据类型如表所示:
数据类型
描述
CHAR
CHAR(n)
INT
SHORT
LONG
FLOAT
DOUBLE
VARCHAR
单字符
n个字符数组
整数
短整数
单精度浮点数
双精度浮点数
变长字符串
这些数据类型实际上就是C语言的数据类型,其中VARCHAR中视为C数据类型的扩充。
这在以后会谈到。
SQL变量的使用应注意以下几点:
●必须在描述部分明确定义
●必须使用与其定义相同的大小写格式
●在SQL语句中使用时,必须在其之前加一个“:
”(冒号),但在C语句中引用时不需加冒号。
●不能是SQL命令中的保留字。
●可以带指示变量。
例如:
EXECSQLBEGINDECLARESECTIONS;
VARCHARprograme[30];
Intporgsal,pempno;
EXECSQLENDDECLARESECTION;
EXECSQLSELECTENAME,SAL
INTO:
programe,:
progsal
FROMEMP
WHEREEMPNO=:
pempno;
(2).指示器变量的说明和引用
指示变量实际上也是一类SQL变量,它被用来管理与其相关联的宿主变量(即在SQL语句中充当输入或输出的变量)。
每一个宿主变量都可定义一个指示器变量,主要用于处理空值(NULL)
指示器变量的说明基本同一般SQL变量一样,但必须定义成2字节的整型,如SHORT、INT。
在SQL语句中引用时,其前也应加“:
”(冒号),而且必须附在其相关联的宿主变量之后,在C语句中,可独立使用。
当指示器变量为-1时,表示空值。
例如:
EXECSQLBEGINDECLARESECTION;
INTdept-number;
SHORTind–num;
CHARemp–name;
EXECSQLENDDECLARESECTION;
Scanf(“90d%s”,&dept-number,dept–name);
If(dept–number==0)
Ind–num=-1;
Else
Ind–num=0;
EXECSQLINSERTINTODEPT(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语句、便可一次性插入。
例如:
EXECSQLBEGINDECLARESECTION;
Intemp_number[100];
Charemp_name[100][15];
Floatsalary[100],commission[100];
Intdept_number;
EXECSQLENDDECLARESECTION;
….
EXECSQLSELECTEMPNO,ENAME,SAL,COMM
INTO:
emp_number,:
emp_name,:
salary,:
commission
FROMEMP
WHEREDEPTNO=:
dept_number;
在使用数组时,应注意以下几点;
●不支持指针数组
●只支持一维数组,而emp-name[100][15]视为一维字符串
●数组最大维数为32767
●在一条SQL语句中引用多个数组时,这些数组维数应相同
●在VALUES,SET,INTO或WHERE子名中,不允许把简单SQL变量与数组SQL变量混用
●不能在DELARE部分初始化数组
例如:
下面的引用是非法的
EXECSQLBEGINDECLARESECTION;
Intdept–num[3]={10,20,30};
EXECSQLENDDECLARESECTION;
EXECSQLSELECTEMPNO,ENAME,SAL
INTO:
emp–num[i],:
emp–name[i],:
salarg[i]
FROMEMP
(5)伪类型VARCHAR的说明和引用
VARCHAR变量在引用之前也必须在说明段说明,说明时必须指出串的最大
长度,如:
EXECSQLBEGINDECLARESECTION;
Intbook–number;
VARCHARbook–name[50];
EXECSQLENDDECLARESECTION;
在预编绎时,book–name被翻译成C语言中的一个结构变量;
Struct{unsignedshortlen;
Unsignedchartarr[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);
EXECSQLUPDATEBOOK
SETBNAME=:
book–name;
BDESC=:
book–number;
}
(6)SQL通信区
SQL通信区是用下列语句描述的:
EXECSQLINCLUDESQLCA;
此部分提供了用户运行程序的成败记录和错误处理。
SQLCA的组成
SQLCA是一个结构类型的变量,它是ORACLE和应用程序的一个接口。
在执行Pro*C程序时,ORACLE把每一个嵌入SQL语句执行的状态信息存入SQLCA中,根据这些信息,可判断SQL语句的执行是否成功,处理的行数,错误信息等,其组成如表所示:
Structsqlca
{charsqlcaid[8];----标识通讯区
longsqlabc;---通讯区的长度
longsqlcode;---保留最近执行的SQL语句的状态码
struct{unsignedshortsqlerrml;-----信息文本长度
}sqlerrm;
charsqlerrp[8];
longsqlerrd[6];
charsqlwarn[8];
charsqlext[8];
}
structsqlcasqlca;
其中,sqlcode在程序中最常用到,它保留了最近执行的SQL语句的状态码。
程序员根据这些状态码做出相应的处理。
这些状态码值如下:
0:
表示该SQL语句被正确执行,没有发生错误和例外。
>0:
ORACLE执行了该语句,但遇到一个例外(如没找到任何数据)。
<0:
表示由于数据库、系统、网络或应用程序的错误,ORACLE未执行该SQL语句。
当出现此类错误时,当前事务一般应回滚。
2.应用程序体
在Pro*C程序中,能把SQL语句和C语句自由地混合书写,并能在SQL语句中使用SQL变量,嵌入式SQL语句的书写文法是:
●以关键字EXECSQL开始
●以C语言的语句终结符(分号)终结
SQL语句的作用主要用于同数据库打交道。
C语言程序用于控制,输入,输出和数据处理等。
(1)连接到ORACLE数据库
在对数据库存取之前,必须先把程序与ORACLE数据库连接起来。
即登录到ORACLE上。
所连接命令应该是应用程序的第一个可执行命令。
连接命令格式如下:
EXECSQLCONNECT:
<用户名>IDENTIFIEDBY:
<口令>
或EXECSQLCONNECT:
<用户名>/<口令>
在使用上述两种格式进行登入时,应当首先在说明段定义包含用户名和口令的
SQL变量,并在执行CONNECT之前设置它们,否则会造成登录失败。
例如:
EXECSQLBEGINDECLARESECTION;
VARCHARusename[20];
VARCHARpassword[20];
EXECSQLENDDECLARE
..........
strcpy(usename.arr,“CSOTT’);
usename.len=strlen(username.arr);
strcpy(password.arr,“TIGER’);
password.len=strlen(password.arr);
EXECSQLWHENEVERSQLERRORGOTOSQLERR;
EXECSQLCONNECT:
usernameINDNTIFIEDBY:
password;
注意:
不能把用户名和口令直接编写到CONNECT语句中,或者把用引号(’)括起来的字母串在CONNECT语句中,如下面的语句是无效的。
EXECSQLCONNECTSCOTTINENTIFIEDBYTIGER;
EXECSQLCONNECT‘SCOTT’IDENTIFIEDBY‘TIGER’;
(2).插入、更新和删除
在讲述SQL语言时已详细讲过,这里就不举例说明了。
(3).数据库查询及游标的使用
在PRO*C中,查询可分为两种类型:
●返回单行或定行数的查询;
●返回多行的查询.此种查询要求使用游标来控制每一行或每一组(主变量用数组).
1)返回单行或定行数的查询
在PRO*C中的查询SQLSELECT语句由以下几个子句组成:
SELECT
INTO
FROM
WHERE
CONNECTBY
UNION
INTERSECT
MINUS
GROUPBY
HAVING
ORDERBY
其中WHERE子句中的查询条件可以是一个属性或多个属性的集合,在执行是赋值的主变量也可放在WHERE子句中.WHERE子句中所用的主变量称为输入主变量。
如:
SELECTEMPNO,JOB,SAL
INTO:
PNAME,:
PJOB,:
PSAL
FROMEMP
WHEREEMPNO=:
PEMPNO;
若没有找到限定的行,则SQLCA.SQLCODE返回”+1403”,表明”没有找到”。
INTO从句中的主变量叫输出主变量,它提供了查询时所需要的信息。
在任何项送给主变量之前,都要求ORACLE把这些项转换成主变量的数据类型。
对于数字是通过截断来完成的(如:
9.23转换为9)。
如果已确定查询只返回一行,那么就不必使用游标,只给SELECT语句增加一个INTO子句即可。
在语义上INTO语句在FROM之前的查询中有多少个选择项就有多少个输出主变量。
若在SELECT项中表达式的数目不等于INTO子句中主变量的数目,就把SQLCA.SQLWARN[3]置为”W”。
2)多行查询及游标的使用
如果查询返回多行或不知道返回多少行,使用带有ORACLE游标(CURSOR)的SELECT语句。
游标是ORACLE和PRO*C存放查询结果的工作区域。
一个游标(已命名的)与一条SELECT语句相关联。
操作游标有由4条命令:
(1)DECLARECURSOR;
(2)OPENCURSOR;(3)FETCH;(4)CLOSECURSOR。
A.定义游标
一个游标必须首先定义,才能使用它。
语法为:
EXECSQLDECLARE〈游标名〉CORSORFOR
SELECT〈列〉
FROM〈表〉
例如:
EXECSQLDECLARECSOR,CURSORFOR
SELECTENAME,JOB,SAL
FROMEMP
WHEREDEPTNO=:
DEPTNO;
当赋给一个与查询相关联的游标CURSOR之后,当SELECT查询EMP时可从数据库中返回多行,这些行就是CURSOR的一个活动区域。
注意:
1)定义游标必须在对游标操作之前完成;
2)PRO*C不能引用没有定义的游标;
3)游标定义后,其作用范围是整个程序。
所以对一个程序来讲,同时定义两个相同的游标是错误的。
B.打开游标
打开游标的OPEN语句主要用来输入主变量的内容,这些主要是WHERE中使用的主变量。
打开游标的语句是:
EXECSQLOPEN〈游标名〉
当打开游标后,可以从相关的查询中取出多于一行的结果。
所有满足查询标准的行组成一集合,叫做“游标活动集”。
通过取操作,活动集中的每一行或每一组是一个一个返回的,查询完成后,游标就可关闭了。
如图所示:
定义游标:
DECLARE
开始查询:
SELECT
打开游标:
OPEN
从活动集取数据:
FETCH
查询完成
关闭游标:
CLOSE
注意:
1)游标处于活动集的第一行前面;
2)若改变了输入主变量就必须重新打开游标。
C.取数据
从活动集中取出一行或一组把结果送到输出主变量中的过程叫取数据。
输出主变量的定义在取数据语句中。
取数据的语句如下:
EXECSQLFETCH〈游标名〉INTO:
主变量1,主变量2,……
FETCH的工作过程如图所示:
查询结果
游标
FETCH
查询结果
在游标打开后
……
如图所示的查询结果指满足查询条件的查询结果。
使用FETCH应注意以下几点:
●游标必须先定义再打开。
●只有在游标打开之后才能取数据,即执行FETCH语句。
●FETCH语句每执行一次,从当前行或当前组取数据一次,下一行或下一组向上移一次。
游标每次所指的行或组都为当前行或当前组,而FETCH每次都是取游标所指定的行或组的数据。
●当游标活动集空之后,ORCLE返回一个SQLCA。
SQLCA(=1403)。
●若希望此游标再操作,必须先关闭再打开它。
●在C程序中可以开辟一个内存空间,来存放操作结果,这样就能利用开辟的空间来灵活操纵查询的结果。
D.关闭游标
取完活动集中所有行后,必须关闭游标,以释放与该游标有关的资源。
关闭游标的格式为:
EXECSQLCLOSE游标名;
例如:
EXECSQLCLOSEC1;
ORACLEV5.0版支持SQL格式“CURRENTOFCURSOR”。
这条语句将指向一个游标中最新取出的行,以用于修改和删除操作。
该语句必须有取操作之后使用,它等同存储一个ROWID,并使用它。
(4).举例
EXECSQLDECLARESALESPEOPLECURSORFOR
SELECTSSNO,NAME,SALARY
FROMEMPLOYEE
WHEREDNAME=‘Sales’;
EXECSQLOPENSALESPEOPLE;
EXECSQLFETCHSALESPEOPLE
INTO:
SS,:
NAME,:
SAL;
EXECSQLCLOSESALESPEOPLE;
(5)SQL嵌套的方法及应用
嵌入SQL与交互式SQL在形式上有如下差别:
1)在SQL语句前增加前缀“EXECSQL”,这一小小的差别其目的是在于预编译时容易识别出来,以便把每一条SQL作为一条高级语言来处理。
2)每一SQL语句分为说明性语句和可执行语句两大类。
可执行语句又分为数据定义、数据控制、数据操纵、数据检索四大类。
可执行性SQL语句写在高级语言的可执行处;说明性SQL语句写在高级语言的说明性的地方。
例如:
在PRO*C程序中建立一个名为BOOK的表结构,过程如下:
#include〈stdio.h〉
EXECSQLBEGINDECLARESECTION;
VARCHARuid[20],pwd[20];
EXECSQLENDDECLARESECTION;
EXECSQLINCLUDESQLCA;
Main()
{
/*logindatabase*/
strcpy(uid.arr,’wu’);
uid.len=strlen(uid,arr);
strcpy(pwd.arr,’wu’);
pwd.len=strlen(pwd.arr);
EXECSQLCONNECT:
uidIDENTIFEEDBY:
pwd;
EXECSQLCREATETABLEbook
(acqnumnumber,copiesnumber,pricenumber);
EXECSQLCOMMITWORKRELEASE;
EXIT;
PRO*C可非常简便灵活地访问ORCLE数据库中的数据,同时又具有C语言高速的特点,因而可完成一些ORACLE产品不能完成的任务,例如以下一个固定的特殊格式输出结果。
SQL嵌套源程序示例
#unclude
typedefcharasciz[20];
EXECSQLBEGINDECLARESECTION;
EXECSQLTYPEascizISSTRING(20)REFERENCE;
ascizusername;
ascizpassword;
ascizemp_name(5);
intemp_number(5a);
floatsalary[5];
EXECSQLENDDECLARESECTION;
EXECSQLINCLUDEsqlca;
Voidprint_rows();
Voidsqlerror();
Main()
{
intnum_ret;
strcpy(username,”SCOTT’);
strcpy(password,“TYGER”);
EXECSQLWHENEVERSQLERRORDOsqlerror();
EXECSQLCONNECT:
usernameIDENTIFIEDBY:
password;
Print(“\nConnectedtoORACLEasuser:
%s\n”,username);
EXECSQLDECLAREc1CURSORFOR
SELECTEMPNO,E