Pro*C概述
一. Pro*C概述
Oracle支持在6种高级语言中嵌入SQL语句,他们分别是C,FORTRAN,PASCAL,COBOL,PL/I和Ada。这些语言统称为宿主语言,用它们开发的应用程序叫PRO程序。如果宿主语言是C,则相应的程序就叫Pro*C,
在Pro*C中可以嵌入SQL语句,利用这些SQL语句可以完成动态的建立,修改和删除数据库中的表,也可以查询,插入,修改和删除数据库表中的行,还可以实现事务的提交和回滚。
二. 应用Pro*C的优缺点
1) 优点:
1. 把过程化语言和非过程语言相结合,可满足各种复杂要求的应用开发。
2. 提高应用程序的执行效率,特别是同ODBC方式的应用相比。
2) 缺点:
1. 可移植性差。
2. 需要预编译。
三. 开发环境
(ア) OS:Windows
(イ) DB:Oracle
(ウ) 预编译环境:Oracle附带的Pro*C/C++以及Oracle提供的库文件
(エ) 编译环境:VC等C编译器
四. 编译过程
Pro*C源代码 -----〉C源代码 -----〉可执行程序
预编译 编译连接
五. Pro*C/C++使用简介
(ア) 位置:Start->Program->Oracle-OraHome81->ApplicationDevelopment->Pro C_C++
(イ) 界面
功能介绍:使用方法
六. Oracle预编译程序的功能和特点如下
(ア) 能用6种高级程序设计语言中的任何一种来编写程序
(イ) 嵌入的SQL语句完全符合ANSI标准
(ウ) 可采用动态SQL技术
(エ) 能开发出满足各种需求的应用程序
(オ) 自动实现内部和外部数据类型的转换
(カ) 可嵌入PL/SQL块
(キ) 能在命令行和程序行上指定预编译可选项
(ク) 能分别与编译
(ケ) 能检查SQL语句和PL/SQL块的语法和语义
(コ) 可利用SQL*Net并行存取多个节点上的Oracle数据
(サ) 可使用数组SQL变量
(シ) 可用高级语言编写SQL*Forms的用户出口
(ス) 能用SQLCA和ORACA进行错误诊断
七. 关于书写格式的说明
(ア) 采用缩进方式编写代码
(イ) 可以使用/*…*/对Pro*C的代码进行注释。
(ウ) 嵌入式SQL语句的关键字应大写。
Pro*C程序设计的基础知识
一. SQL变量
(ア) Pro*C程序中含有C和SQL两种语言的语句,为了解决他们之间传递信息的问题,特引入了一种变量,称为SQL变量。
(イ) SQL变量可以在SQL语句中引用,也可以在C语句中引用,而在C代码里定义的变量则只能在C代码部分引用。同C的变量一样,SQL变量也必须在使用前进行申明。否则在预编译时会产生如下错误信息。Undeclared host variable “X” at line N in file “F”
二. 说明段
(ア) SQL变量必须在说明段进行说明,说明段的语句由EXEC SQL BEGIN DECLARE SECTION开始,由EXEC SQLEND DECLARE SECTION语句结束。
(イ) 在Pro*C中允许定义局部和全局的说明段,在预编译单位内允许有多个说明段,但至少有一个全程说明段。说明段的任务是说明SQL变量的数据类型。
例:
EXEC SQL BEGIN DECLARE SECTION
VARCHARname[15];
VARCHARpasswd[20];
int emp_no;
float salary;
chardept_name[50];
short ind_sal;
EXEC SQL END DECLARE SECTION;
三. 数据类型
(ア) 常用的SQL变量的数据类型
char
char[n]
int
short
long
float
double
VARCHAR[N]
这些类型实际上就是C的数据类型,其中VARCHAR可视为C数据类型的扩充。Pro*C预编译时将会把VARCHAR[N]的变量定义预编译成
struct { unsigned short len; unsigned char arr[N]; } ;
这样的C类型。
(イ) SQL变量的等价
char,char[n],char* VARCHAR2
char,char[n],char* CHAR
int,int* INTEGER
short,short* INTEGER
long,long* INTEGER
float,float* FLOAT
double,double* FLOAT
VARCHAR(N) VARCHAR
….请参见附录
(ウ) SQL变量的说明和引用
① 对于简单C类型只能说明一维数组,不允许说明二维或更高维数的数组。对于char username[15][50];这样的说明,ORACLE将是为一维数组。
② 对标准的C数据类型,能使用一个说明语句同时说明多个SQL变量。
③ Pro*C允许在说明段对SQL变量进行初始化,但是不允许对数组进行初始化,例如下面的语句是错误的。
EXEC SQL BEGIN DECLARE SECTION
int dept_id[3]= {10,20,30};
EXEC SQL END DECLARE SECTION
实际根据我调查的结果,这样的初始化定义是被允许的,与编译是没有问题,在使用中也没有问题。可能在使用VARCHAR时会出现问题,所以才不禁止对SQL变量进行初始化。
④ SQL变量定义中允许出现的存储类型
1. auto
2. extern
3. static
⑤ 在说明SQL变量的数据类型时,为变量指定的数据类型必须与ORACLE的数据类型相兼容,否则会产生数据类型转换错误。
CHAR(X) char 单字符
char[n] n字节的字符
VARCHAR2(Y) VARCHAR[n] n字节的变长字符数组
int 整数
short 短整数
long 长整数
float 单精度浮点数
double 双精度浮点数
NUMBER int 整数
short 短整数
NUMBER(P,S) long 长整数
Float 单精度浮点数
Double 双精度浮点数
Char 单字符
Char[n] n字节字符数组
VARCHAR[n] n字节变长字符数组
DATE char[n] n字节字符数组
LONG VARCHAR[n] n字节变长字符数组
RAW(X) unsigned char[n] n字节无符号字符数组
LONG RAW VARCHAR[n] n字节变长字符数组
⑥ SQL变量的引用
当SQL语句中使用SQL变量时,必须在其之前加一个冒号(:),但在C语句中引用时,不需要加冒号。例如:
EXEC SQL BEGIN DECLARE SECTION;
Int emp_number;
Float salary;
Floatcommission;
EXEC SQL END DECLARE SECTION;
…
printf(“\nEnteremployee number”);
scanf(“%d”,&emp_number);
EXEC SQL SELECT SAL,COMM
INTO :salary,:commission
FROM EMP
WHERE EMPNO =:emp_number;
Pay = salary + commission;
….
⑦ 指示器变量的说明和引用
1. 什么是指示器变量
指示器变量时与宿主变量相关的一类SQL变量,它被用来监督和管理与其相关联的宿主变量。每一个宿主变量都可以定义一个指示器变量。指示器变量的具体作用如下:
向数据库表列输入Null值。
检查从数据库表列中选取的数据是否是null值,或是否发生截断问题。
2. ORACLE如何实现指示器变量的上述作用呢?其办法是赋予它不同的值:
(ア) 对于输入宿主变量:
① -1:ORACLE把Null值存入数据库的表列中,而不考虑于该指示器变量相关联的输入宿主变量的值。
② >=0:ORACLE把与该指示器变量相关联的输入宿主变量中的数据存入数据库表列中。
(イ) 对于输出宿主变量:
① -1:数据库表列的值是Null,此时,与该指示器变量相关联的输出宿主变量中的值为不确定状态。
② 0:数据库表列中的值原封不动的赋给与该指示器变量相关联的输出宿主变量中。
③ >0:ORACLE把数据库表列中的值截断后赋给与该指示器变量相关联的输出宿主变量中,指示器变量返回一个整数值,指示该列值的原始长度,而且SQLCA的SQLCODE被置为0。
3. 指示器变量的说明 – 同一般的SQL变量,类型为SHORT
4. 指示器变量的引用
EXEC SQL SELECT EMPNO
INTO:emp_number :ind_num
FROM EMP
WHERE ENAME =:emp_name;
If(ind_num == -1)
Printf(“\nEmploylee Number is Null!”);
⑧ 指针宿主变量的说明和引用
1. 指针宿主变量的说明
同C语言一样,Pro*C也支持指针宿主变量。其说明格式同C语言。例:
EXEC SQL BEGIN DECLARE SECTION;
Int *ptr;
Char *pname;
EXEC SQL END DECLARE SECTION;
2. 引用
在SQL语句中引用指针变量时,指针名字前要前缀冒号(:),而不加星号(*)。在C语句中的用法同C语言的指针变量一样。例:
EXEC SQL BEGIN DECLARE SECTION;
Float salary;
Char *pname;
Int emp_number;
EXEC SQL END DECLARE SECTION;
….
EXEC SQL SELECT ENAME,SAL
INTO:pname,:salary
FROM EMP
WHEREEMPNO = :emp_number;
Printf(“%s,%f”,pname,salary);
⑨ 数组SQL变量的说明和引用
1. 说明
说明格式同C语言
注意:
PRO*C不支持指针数组
PRO*C只支持一维数组,如emp_name[100][15]将被视为一维字符串。
数组最大维数为32767,如果超出次限制,则出现“parameter out ofrange”错误。
2. 数组SQL变量的引用
在SQL语句中引用数组时,只需写数组名,不需要写下标。例:
EXEC SQL BEGIN DECLARE SECTION;
Intemp_number[100];
Charemp_name[100][15];
Floatsalary[100],commission[100];
Intdept_number;
EXEC SQL END DECLARE SECTION;
…
EXEC SQL SELECT EMPNO,ENAME,SAL,COMM
INTO:emp_number,:emp_name, :salary, :commission
FROM EMP
WHERE DEPTNO =:dept_number;
而如下写法则是错误的
for(I=1; I<=100; I++)
EXEC SQL SELECTEMPNO, ENAME, SAL, COMM
INTO:emp_number[I], :emp_name[I], :salary[I], :commission[I]
FROM EMP
WHERE DEPTNO =:dept_number;
3. 使用数组变的好处和注意点
好处:
大大简化程序设计,省去大量不必要的变量命名及引用。
改进程序性能。如在SQL语句中,如果没有数组,就需要循环重复执行。可大大降低网络传输开销。
注意点:
当在SQL语句中引用多个数组时,这些数组的维数应当相同,否则PRO*C使用最小的数组维数,并发出警告。
在VALUES、SET、INTO或WHERE子句中,不允许把简单SQL变量与数组SQL变量混用。
在UPDATE或DELETE语句中,不允许把数组与CURRENT OF子句一起使用。
(エ) 通讯区的说明
① SQLCA的说明
1. 什么是SQLCA:SQLCA时一个结构类型的变量,它是ORACLE和应用程序的一个接口。该结构变量是为诊断错误和事件处理而设置的。在执行PRO*C程序时,ORACLE把每一个嵌入SQL语句执行的状态信息存入SQLCA中,这些信息包括错误代码、警告标志设置,诊断文本和处理行数等。每一个可执行SQL语句执行后,就可根据SQLCA中的状态信息来判断该SQL语句的执行是否成功?出现什么错误和例外?处理了多少行?等等。
2. SQLCA的组成:参见SQLCA.H
3. SQLCA的说明方式
EXEC SQL INCLUDE sqlca;
一个PRO*C程序可说明多个SQLCA,例如可以有一个全程SQLCA和几个局部SQLCA。ORACLE仅对活动的SQLCA返回信息。
当PRO*C程序是由几个源文件组成时,全局SQLCA可以在一个源文件中定义,而在另一个源文件中说明为extern存储类,其说明方式是:
#define SQLCA_STORAGE_CLASS extern;
② ORACA的说明
1. 什么是ORACA:ORACA是一个类似于SQLCA的数据结构,可把它视为SQLCA的辅助通讯区。当需要的错误及状态信息比SQLCA提供的还要多是,就用ORACA。ORACA的使用时可选的,因为它会增加系统的运行开销。
2. ORACA的声明:同SQLCA(为了能够使用ORACA,必须把ORACA与编译可选项指定为“YES”。指定方式为在程序行商编写EXEC ORACLE OPTION(ORACA=YES);)
应用程序的设计方法及举例
一. PRO*C程序中嵌入的SQL语句
(ア) PRO*C程序中能嵌入的SQL语句,见下表
语句类型 |
语句名 |
数据定义 |
ALTER,ANALYZE,AUDIT, COMMENT,CREATE,DROP, GRANT,NOAUDIT,RENAME, REVOKE,TRUNCATE |
数据操纵 |
DELETE,EXPLAINPLAN,INSERT, LOCK,TABLE,SELECT,UPDATE |
会话期控制 |
ALTER,SESSION,SET,ROLE |
系统控制 |
ALTER,SYSTEM |
事务控制 |
COMMIT,ROLLBACK,SAVEPOINT,SET,TRANSACTION |
(イ) 嵌入式SQL语句的书写文法
① 以关键字EXEC SQL开始
② 以C语言的语句终结符(分号)终结
③ 大多数嵌入式SQL语句与交互式SQL语句的区别仅仅是增加了一些子句活使用了一些SQL变量。例:
交互式的写法:
SELECT EMPNO,ENAME,SAL,DEPTNO
FROM EMP
WHERE ENAME=‘ALLEN’;
ROLLBACK WORK;
嵌入式的写法:
EXEC SQLSELECT EMPNO,ENAME,SAL,DEPTNO
INTO :emp_number, :emp_name, :salary, :deptno
FROM EMP
WHERE ENAME = ‘ALLEN’;
EXEC SQLROLLBACK WORK;
二. 连接到数据库
(ア) 连接当前节点的缺省数据库
EXEC SQL CONNECT :username IDENTIFIED BY :password;
或EXEC SQL CONNECT :usr_pwd;其中宿主变量usr_pwd内包含由字符“/”分隔的用户名和口令(即username/password)
(イ) 连接到其他数据库
下面的例子是对一个远程节点上的单个非缺省数据库进行登录:
/*命名一个连接名*/
EXEC SQL DECLARE nridb DATABASE;
int ConnectDB(char *dbName, char *uid, char *pwd)
{
EXEC SQLWHENEVER SQLERROR GOTO errexit;
EXEC SQLCONNECT :uid IDENTIFIED BY :pwd AT nridb USING :dbName;
return (0);
errexit:
errrpt();
EXEC SQL WHENEVERSQLERROR CONTINUE;
EXEC SQL ROLLBACKWORK RELEASE;
return(-1);
}
如果授权的话,可在给连接上执行任意的SQL语句,如:
EXEC SQL AT nridb SELECT …
EXEC SQL AT nridb INSERT…
EXEC SQL AT nridb UPDATE…
另一种方法是将连接名放在SQL变量中使用
可以是这样的用法:
EXEC SQL BEGIN DECLARE SECTION;
Chardb_link[10];
Char unid[10];
Char pwd[10];
Chardbname[10];
EXEC SQL END DECLARE SECTION;
…
strcpy(dblink,”nridb”);
strcpy(uid,”SCOTT”);
strcpy(pwd,”TIGER”);
strcpy(dbname,”nridb”);
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd
AT:dblink USING :dbname;
EXEC SQL AT :dblink SELECT …
三. 静态数据库操作(插入、更新和删除)
(ア) 数据插入
一次插入一行:
EXEC SQL INSERT
INTOEMP(EMPNO,ENAME,JOB,SAL)
VALUES(:emp_number,:emp_name,:job,:salary);
一次插入多行:
EXEC SQL BEGIN DECLARE SECTION;
Charemp_name[100][20];
Floatsalary[100];
Intinsert_rows;
EXEC SQL END DECLARE SECTION;
…
insert_rows = 50;
EXEC SQL FOR :insert_rows
INSERT INTOEMP(ENAME,SAL)
VALUES(:emp_name,:salary);
(イ) 数据更新
EXEC SQL UPDATE EMP …
(ウ) 数据删除
EXEC SQL DELETE FROM EMP …
(エ) 修正后累计修改行数在SQLCA.SQLERRD[2]中返回。如果省略WHERE子句,则在SQLCA的SQLWARN[4]中设置警告标志。
四. 查询应用
(ア) 简单查询
语句:EXEC SQL SELECT EMPNO,ENAME,SEX,OLD
INTO:emp_number,:emp_name,:sex,:old
FROM EMP
WHERE EMPNO =65147;
(イ) 利用数组实现返回多行的查询
EXEC SQL BEGIN DECLARE SECTION;
Charemp_name[100][20];
Floatsalary[100];
Floatcommission[100];
EXEC SQL END DECLARE SECTION;
…
EXEC SQL SELECT ENAME,SAL,COMM
INTO:emp_name,:salary,:commission
FROM EMP
WHERESAL>500.00;
该SELECT至多只能返回100行。如果满足选择条件的行不超过100行,或者用户只希望检索开始100行时,可用这种方式处理。如果超过100行,则其只返回开始的100行数据,如果再次执行该操作,仍返回开始的100行。所以对于这种情况,必须把数组说明得足够大。
使用注意:
只要INTO子句中的宿主变量其中一个是数组,则其他必须都是数组。这些数组可以有不同的维数,此时能够处理的数组元素个数由最小的数组元素个数决定。不允许在WHERE子句中使用数组。
选择的累计行数在SQLCA.SQLERRD[2]中返回。
SELECT语句中不允许使用FOR子句。
(ウ) 使用光标实现返回多行的查询
① 步骤是:
1. 说明一个光标,并使他与一个SELECT语句或PL/SQL块相关联。
2. 打开该光标,把满足查询条件的行(或记录)都检索到该光标缓冲区中。
3. 提取:从光标缓冲区中一次一行或多行的取出数据,进行处理,直至取完。
4. 关闭光标,释放缓冲区等。
② 相关的四条语句:
1. DECLARECURSOR:命名一个光标,并使它与一个SELECT语句或PL/SQL块相关联。
2. OPEN:打开光标,把满足条件的行都检索到该光标缓冲区中,使光标指向该缓冲区中的第一行。
3. FETCH:从光标缓冲区中提取行。
4. CLOSE:关闭光标,释放空间。
③ 例:
EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECTEMPNO,ENAME,JOB,SAL,COMM
FROM EMP
WHEREDEPTNO = 1010;
EXEC SQL OPEN emp_cursor;
…
for(;;){
EXEC SQLWHENEVER NOTFOUND DO break;
EXEC SQL FETCHemp_cursor
INTO:emp_number,:emp_name,:job,:salary,:commission;
}
EXEC SQL CLOSE emp_cursor;
五. 在PRO*C程序中嵌入PL/SQL
(ア) 嵌入PL/SQL块的优点
① 改进性能
使用嵌入SQL语句系统一次只能传送一个SQL语句给服务器。使用PL/SQL块,则一次可以传送一个完整的块给服务器。可以大大提高程序运行的效率。
② 与ORACLE紧密集成
大多数PL/SQL数据类型对ORACLE数据字典来说都是其自身的数据类型。可以提供数据的相对独立性,降低维护代价,并使程序适应数据库的变化。
③ 等等优点,由于这些属于PL/SQL的范畴,在此不做过多的讨论。着重讨论如何在PRO*C中嵌入PL/SQL块的方法。
(イ) 嵌入PL/SQL块的方法
ORACLE预编译程序处理PL/SQL块的方法类似于处理单个SQL语句。因此,在PRO*C程序中凡是能放置SQL语句的地方都能放置PL/SQL块。但是,PL/SQL块必须用关键词EXEC SQL EXECUTE和END_EXEC括住。注意EXEC SQL EXECUTE后不要有“;”最后END_EXEC结束后必须有“;”
(ウ) 使用宿主变量
① 在PL/SQL块内,把宿主变量作为整个块的全程变量来处理,凡是能允许PL/SQL变量的地方都能使用宿主变量。
② VARCHAR变量的引用:在嵌入是PL/SQL块中也可以使VARCHAR变长字符串,其方法类似嵌入SQL语句,但维一不同点是:当VARCHAR变量是一个输出宿主变量时,在进入该块之前应初始化其长度字段,即把长度字段设置为VARCHAR变量的说明长度。如下例所示:
EXEC SQL BEGIN DECLARE SECTION;
Int dept_number;
VARCHARdept_name[50];
…
EXEC SQL END DECLARE SECTION;
…
dept_name.len = 50;
EXEC SQL EXECUTE
BEGIN
SELECTDNAME
INTO :dept_name
FROM DEPT
WHERE DEPTNO = :dept_number;
…
END;
END_EXEC;
六. 错误处理
(ア) 使用WHENEVER语句进行错误处理
WHENEVER语句是说明性语句。当执行SQL语句发生错误、警告或找不到等情况时,可用它来指出应采取的动作。使用该语句来诊断SQL错误是最简单、最常用和最有效的方法。
WHENEVER语句的格式
EXEC SQL WHENEVER {SQLERROR | NOTFOUND | SQLWARNING}
{CONTINUE | DOfunction call | DO break | GOTO lable_name | STOP};
注意STOP时仅停止程序运行,但不提交和回滚事务。
(イ) 显示测试SQLCA
显式测试SQLCA,就是可在每一个可执行SQL语句后编写一段代码,来测试SQLCA,以确定该SQL语句的执行是否发生错误,发生什么错误,并进行相应的处理。例如:
EXEC SQL INSERT ….
If(sqlca.sqlcode < 0){
Printf(“Insert Error!!!\n”);
…
}
事务处理
一. 提交事务
(ア) COMMIT语句常用的书写格式如下:
EXEC SQL COMMIT WORK RELEASE;
EXEC SQL AT :db_link_name COMMIT WORK;
二. 回滚事务
(ア) 事务保留点:
EXEC SQL AT :db_link_name SAVEPOINT savepoint_name;
EXEC SQL SAVEPOINT savepoint_name;
(イ) 事务回滚
事务级回滚
EXEC SQL ROLLBACK WORK RELEASE;
EXEC SQL AT :db_link_name ROLLBACK WORK RELEASE;
部分事务回滚
EXEC SQL ROLLBACK WORK TO SAVEPOINT savepoint_name;
EXEC SQL AT :db_link_name ROLLBACK WORK
TOSAVEPOINT savepoint_name;
(ウ) 表封锁
EXEC SQL LOCK TABLE EMP IN ROW SHARE MODE NOWAIT;
(エ)
补充说明:
注意: 不能把用户名和口令直接编写到CONNECT语句中,或者把用引号(’)括起来的字母串在CONNECT 语句中, 如下面的语句是无效的。
EXEC SQL CONNECT SCOTT INENTIFIED BYTIGER;
EXECSQL CONNECT ‘SCOTT’ IDENTIFIED BY ‘TIGER’;
(7) 动态定义语句
SQL语句分动态定义语句和静态定义语句两种:
(1)静态定义语句:SQL语句事先编入PRO*C中,在经过预编译器编译之后形成目标程序*。BOJ,然后执行目标程序预即可。
(2)动态定义语句:有些语句不能事先嵌入到PRO*C程序中,要根据程序运行情况,用户自己从输入设备上(如终端上)实时输入即将执行的SQL语句。
动态定义语句有:
l EXECUTE IMMEDIATE;
l PREPARE 与EXECUTE;
l PREPARE与FETCH 和 OPEN ;
l BIND与DEFINE DESCRIPTOR。
1. EXECUTE IMMEDIATE语句
此语句表示立即执行, 并且只向SQLCA返回执行结果,无其它信息。例如:
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR abcd[89];
VARCHARdeay[20];
EXEC SQL END DECLARE SECTION;
/** 输出字符串到abcd **/
EXECSQL EXECUTE IMMEDIATE :abcd;
注意:
1) EXECUTE IMMEDIATE只能运行带一个参数的动态语句。其中,abcd是参数,不是关键字。
2) EXECUTE IMMEDIATE使用的先决条件是:SQL语句不能包含主变量;SQL语句不能是查询语句。
3) 可用任何主变量作为EXECUTEIMMEDIATE的参数;也可用字符串作为主变量。
2. PREPARE与EXECUTE语句
此语句表示“预编译/执行”。此语句能够预编译一次而执行多次。语法为:
EXECSQL PREPARE 〈语句名〉FROM:主变量;
EXECSQL EXECUTE〈语句名〉[USING:替换主变量];
PREPARE语句做两件事:
(1) 预编译SQL语句;
(2) 给出SQL语句的语句名。
注意:
l SQL语句不能是查询语句;
l PREPARE和EXECUTE可包含主变量;
l PREPARE不能多次执行。
例如:<example.pc>
#defineUSERNAME “SCOTT”
#definePASSWORD “TIGER”
#include<stdio.h>
EXECSQL INCLUDE sqlca;
EXECSQL BEGIN DECLARE SECTION;
Char * username=USERNAME;
Char * password=PASSWORD;
VARCHAR sqlstmt[80];
Int emp_number;
VARCHAR emp_name[15];
VARCHAR job[50];
EXECSQL END DECLARE SECTION;
Main()
{
EXECSQL WHENEVER SQLERROR GOTO :sqlerror;
EXECSQL CONNECT :username IDENTIFIED BY :password;
Sqlstmt.len=sprintf(sqlstmt.arr,”INSERTINTO EMP (EMPNO,ENAME,JOB,SAL)
VALUES(:V1,:V2,:V3,:V4)”);
Puts(sqlstmt.arr);
EXECSQL PREPARE S FROM :sqlstmt;
For(;;)
{
printf(“\nenter employee number:”);
scanf(“%d”,&emp_number);
if (emp_number==0) break;
printf(“\nenter employee name:”);
scanf(“%s”,&emp_name.arr);
emp_name.len=strlen(emp_name.arr);
printf(“\nenter employee job:”);
scanf(“%s”,job.arr);
job.len=strlen(job.arr);
printf(“\nenter employee salary:”);
scanf(“%f”,&salary);
}
EXECSQL EXECUTE S USING :emp_number,:emp_name,:job,:salary;
}
3. FETCH语句和OPEN语句
FETCH语句和OPEN语句这组动态语句是对游标进行操作的,其执行过程如下:
PREPARE〈语句名〉FROM 〈主变量字符串〉; |
DECLARE〈游标名〉FOR〈语句名〉; |
OPEN 〈游标名〉[USING:替换变量1[,:替换变量变…]] |
FETCH〈游标名〉INTO: 主变量1[,:主变量2…] |
CLOSE〈游标名〉 |
注意:
l SQL语句允许使用查询语句;
l SELECT子句中的列名不能动态改变,只能预置;
l WHERE和ORDER BY 子句可以动态改变条件。
还有第四种方法比较复杂,请另外单独查阅资料;
以上都是预编译选项dynamic为oracle(默认)时的方法,如果该选项设置为ANSI,则方法不太一样,也请另外查阅资料。