procc 编程需要oracle11.lib,使用PRO*C编程的一些说明和例子及错误处理方法(3)

(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];

VARCHAR deay[20];

EXEC SQL END DECLARE SECTION;

EXEC SQL EXECUTE IMMEDIATE :abcd;

注意:

1) EXECUTE IMMEDIATE只能运行带一个参数的动态语句。其中,abcd是参数,不是关键字。

2) EXECUTE IMMEDIATE使用的先决条件是:SQL语句不能包含主变量;SQL语句不能是查询语句。

3) 可用任何主变量作为EXECUTE IMMEDIATE的参数;也可用字符串作为主变量。

2.

PREPARE与EXECUTE语句

此语句表示“预编译/执行”。此语句能够预编译一次而执行多次。语法为:

EXEC SQL PREPARE 〈语句名〉FROM:主变量;

EXEC SQL EXECUTE〈语句名〉[USING:替换主变量];

PREPARE语句做两件事:

(1) 预编译SQL语句;

(2) 给出SQL语句的语句名。

注意:

l SQL语句不能是查询语句;

l PREPARE和EXECUTE可包含主变量;

l PREPARE不能多次执行。

例如:

#define

USERNAME “SCOTT”

#define PASSWORD “TIGER”

#include <stdio.h>

EXEC SQL INCLUDE sqlca;

EXEC SQL BEGIN DECLARE SECTION;

Char * username=USERNAME;

Char * password=PASSWORD;

VARCHAR sqlstmt[80];

Int emp_number;

VARCHAR emp_name[15];

VARCHAR job[50];

EXEC SQL END DECLARE

SECTION;

Main()

{

EXEC SQL WHENEVER SQLERROR GOTO :sqlerror;

EXEC SQL CONNECT :username

IDENTIFIED BY :password;

Sqlstmt.len=sprintf(sqlstmt.arr,”INSERT

INTO EMP (EMPNO,ENAME,JOB,SAL)

VALUES(:V1,:V2,:V3,:V4)”);

Puts(sqlstmt.arr);

EXEC SQL 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);

}

EXEC SQL 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 子句可以动态改变条件。

第一个Proc程序

1、环境的搭建

安装好ORACLE后,在用户.profile文件中添加

LD_LIBRARY_PATH=/usr/lib:$ORACLE_HOME/lib:$ORACLE_HOME/ctx/lib:$ORACLE_HOME/rdbms/lib

然后

export LD_LIBRARY_PATH

2、在命令行执行proc正确后,在文件/oracle_install/product/10.2.0.1/precomp/admin/pcscfg.cfg中添加如下内容:

sys_include=(/ade/aime_rdbms_9819/oracle/precomp/public,/usr/include,/usr/lib/gcc-lib/i486-suse-linux/2.95.3/include,/usr/lib/gcc-lib/i386-redhat-linux/3.2.3/include,/usr/lib/gcc-lib/i386-redhat-linux7/2.96/include)

ltype=short

code=cpp

cpp_suffix=cc

parse=none

SQLCHECK=SEMANTICS

注:关于code=cpp,这里有三种模式,code=cpp、code=kr_c、code=ansi_c。采用何种方式决定了与编译proc编译后的文件后缀名和函数原型的方式。

2.1 code=cpp

此时,与编译将采用C++的原型编译方式,编译后的文件以.cc结尾。

2.2 code=kr_c和code=ansi_c

此时编译器都将按照C语言的原型方式编译,编译后文件以.c结尾。两者的区别是:

当采用code=kr_c的方式编译时,原型编译为如下形式:

extern void sqlora() ;

当采用code=ansi_c的方式编译时,原型编译形式如下:

extern void sqlora(long *, void *) ;

3、编写源程序first.pc。

#include <stdio.h>

EXEC SQL include sqlca.h ;

EXEC SQL BEGIN DECLARE SECTION ;

char *uid = "";

char *username = "guoxin";

char *password = "guoxin";

char *conn_name = "10.10.10.22:1521/ipuser";

char *db_link_name = "ipuser";

EXEC SQL END DECLARE

SECTION ;

int main()

{

EXEC SQL CONNECT :uid;

//or EXEC

SQL CONNECT :username

IDENTIFIED BY :password

USING :conn_name;

if (sqlca.sqlcode == 0) {

printf("Conn

OK;/n") ;

} else {

printf("Conn

ERROR;/n") ;

}

return 0 ;

}

4、编写Makefile文件。

CC=g++

first:

proc first.pc

${CC} -o first -I$(ORACLE_HOME)/precomp/public/

-L$(ORACLE_HOME)/lib/ -lclntsh first.cc

rm -rf t* first.lis first.cc

clean:

rm -rf t* first.lis first.cc

rm -rf first

值得说明的是,如果我们采用code=cpp的方式编译,CC必须使用g++编译器,否则报错;如果采用code=ansi_c/code=kr_c的方式编译,则可使用C语言的编译器,如cc、gcc等。上述给出的是采用code=cpp的方式编译的,下面给出code=ansi_c/code=kr_c的makefile文件。

CC=cc

first:

proc first.pc

${CC} -o first -I$(ORACLE_HOME)/precomp/public/

-L$(ORACLE_HOME)/lib/ -lclntsh first.c

rm -rf t* first.lis first.c

clean:

rm -rf t* first.lis first.c

rm -rf first

注意此时的first.cc都变成了first.c文件。

5、执行make命令,则输出如下结果:

proc first.pc

Pro*C/C++:

Release 10.2.0.1.0 - Production on Thu Jan 15 15:23:19

2009

Copyright

(c) 1982, 2005, Oracle. All rights reserved.

System

default option values taken from:

/oracle_install/product/10.2.0.1/precomp/admin/pcscfg.cfg

g++ -o

first -I/oracle_install/product/10.2.0.1/precomp/public/

-L/oracle_install/product/10.2.0.1/lib/ -lclntsh -lecpg

first.cc

rm -rf t* first.lis first.cc

表明执行成功,通过ls命令可以看到first执行程序已经成功被编译出来。

$ ls

first first.pc makefile

$ 6、运行first。

$ ./first sqlca.sqlerrm.sqlerrmc:[];

Conn OK;

$ 至此,第一个proc程序结束。

注意:

oracle proc PCC-S-02015错误

错误信息:

System default option values taken from:

/u01/app/oracle/product/10.1.0/precomp/admin/pcscfg.cfg

Error at line 34, column 11 in file /usr/include/stdio.h

# include

..........1

PCC-S-02015, unable to open include file

Error at line 31, column 10 in file

/usr/include/bits/types.h

#include

.........1

PCC-S-02015, unable to open include file

Error at line 14, column 10 in file

/usr/include/_G_config.h

#include

.........1

PCC-S-02015, unable to open include file

Error at line 48, column 10 in file /usr/include/wchar.h

#include

.........1

PCC-S-02015, unable to open include file

Error at line 48, column 10 in file /usr/include/wchar.h

#include

.........1

PCC-S-02015, unable to open include file

Error at line 31, column 10 in file /usr/include/gconv.h

#include

.........1

PCC-S-02015, unable to open include file

解决修改:$ORACLE_HOME/precomp/admin/pcscfg.cfg

(网络上很多答案是添加选项parse=none,意思是忽略头文件预编译.如果说含有宏定义则根本没有解决.不提倡)

在/usr/lib/下查找未找到的"stddef.h"文件,找到路径在pcscfg.cfg修改或添加该路径.

find . -name "stddef.h" -print ./gcc-lib/i386-redhat-linux/3.2.3/include/stddef.h

原来:sys_include=(/tmp/p/precomp/public,/usr/include,/usr/lib/gcc-lib/i486-suse-linux/3.2.2/include,/usr/lib/gcc-lib/i486-suse-linux/3.2/include,/usr/lib/gcc-lib/i386-redhat-linux/4.0.0/include,/usr/lib/gcc-lib/i386-redhat-linux7/3.2.3/include,/usr/lib/gcc-lib/i586-suse-linux/3.3.3/include)

改为:

sys_include=(/tmp/p/precomp/public,/usr/include,/usr/lib/gcc-lib/i486-suse-linux/3.2.2/include,/usr/lib/gcc-lib/i486-suse-linux/3.2/include,/usr/lib/gcc-lib/i386-redhat-linux/3.2.3/include,/usr/lib/gcc-lib/i386-redhat-linux7/3.2.3/include,/usr/lib/gcc-lib/i586-suse-linux/3.3.3/include)

如果使用时为乱码,执行 export NLS_LANG="Simplified Chinese_china.AL32UTF8"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值