从ESQLC移植到PROC

    技术2022-05-11  16

    本文档讲述数据库嵌入式 SQL/C语言程序从ESQLC向PROC移植过程中所进行的分析、移植过程,并讲述如何编写可通用的嵌入式SQL/C语言程序。 作者:余军, 2007年5月9日   第一部分:ESQLC,PROC差异性分析 一.基本语法 1.语法字符 ESQLC中既支持‘ $’数据库语法,同时也支持“EXEC SQL”,‘:’数据库语法 PROC中只支持“ EXEC SQL”,‘:’数据库语法   2.数据库变量定义 ESQLC中支持 3种表达方法 方法 1, $int nValue; $char strValue[20]; 方法 2(会有警告,但不影响编译及运行结果), EXEC SQL int nValue; EXEC SQL char strValue[20]; 方法 3, EXEC SQL BEGIN DECLARE SECTION; int nValue; char strValue[20]; EXEC SQL END DECLARE SECTION;   PROC中支持 2种表达方法 方法 1,不加任何修饰,即与非数据库变量的定义相同 方法 2, EXEC SQL BEGIN DECLARE SECTION; int nValue; char strValue[20]; EXEC SQL END DECLARE SECTION;   3.数据库变量的使用 ESQLC中对‘ $’,‘:’均能支持 PROC中只能用‘ :’   4.基本的SQL语句(查询、插入、删除、修改) ESQLC, sql语句中可以用数据库变量,也可以用常量,如where name= '张三' PROC, sql语句中只能用数据库变量,如where name= :m_name   二.高级SQL操作(游标等) 1.数据库打开、关闭操作 ESQLC中打开数据库使用 database 数据库名,关闭数据库使用database close PROC中打开数据库使用 CONNECT :username IDENTIFIED BY :password,不用关闭   2.事务操作 ESQLC中语法 打开事务, begin work; 提交事务, commit work; 回滚事务, rollback work; PROC中语法 打开事务,不写 提交事务, commit work; 回滚事务, rollback;   3.游标操作 游标基本语法 定义游标, declare cur名称 cursor for sql语句 打开游标, open cur_1或open cur_1 using :con1,:con2 Fetch游标, fetch cur_1或fetch cur_1 into :val1,:val2 关闭游标, close cur_1 释放游标, free cur_1   两平台区别: sql语句区别同基本 sql语句,PROC中不能用用常值(where name= '张三'),只能用数据库变量(where name= :m_name)。 PROC中不能释放游标,而 ESQLC中要求释放游标。   三.数据库操作运行结果 1.表达符 ESQLC中一般采用 SQLCODE,也可采用sqlca.sqlcode PROC中只能用 sqlca.sqlcode。   2.常用数值含义 开发阶段 含义 Informix, ESQL/C Oracle, PROC 插入时列数不匹配 -236 (待查) 字段不存在 -217 (待查)   运行阶段 含义 Informix, ESQL/C Oracle, PROC 找到数据 0 0 找不到数据 100 1403 插入时重复 -239 -1 找到记录不唯一 (待查) (待查) 范围超限 (待查) 1480 找到值为 NULL (待查) -1405 其他(待续)       四.程序的编译及链接 1.基本命令 ESQLC预编译命令 esql PROC预编译命令 proc   2.编译语法 ESQLC中 makefile的一般写法 CC=cc ECC=$(INFORMIXDIR)/bin/esql   .SUFFIXES:.ec .SUFFIXES:.c .ec.o:         $(ECC) -c $*.ec         rm -f $*.c   .c.o:         $(CC) -c $*.c   PROC中 makefile的一般写法 CC=cc PROC=proc userid=用户名 /密码 sqlcheck=full char_map=string INCLUDE=头文件目录 CFLAGS=编译参数   .SUFFIXES:.c .SUFFIXES:.pc   .pc.o:         $(PROC) $(INCLUDE) iname=$*.pc oname=$*.c         $(CC) -I$(INCLUDE) $(CFLAGS) -c -o $*.o $*.c         rm -f $*.c         rm -f $*.lis   .c.o:         $(CC) -I$(INCLUDE) $(CFLAGS) -c -o $*.o $*.c   3.链接语法 ESQLC中, $(ECC) -o 可执行文件 链接文件1 连接文件2 … PROC中, $(CC) -o 可执行文件 链接文件1 连接文件2 … 其中链接文件,可以事 obj文件,静态库文件,源文件等。   第二部分:移植步骤 不同风格的 ESQLC程序,采用不同的移法,总之越接近PROC,则越容易移植,这里讲述与PROC风格相差最大的ESQLC程序(采用‘$’作为数据库操作标识符)的移植方法。   一.程序移植 编辑工具采用 UltraEdit,应用多文件替换操作。 1.程序修改 步骤 1,先修改操作语句,即将‘$’修改“EXEC SQL ” Informix, ESQL/C Oracle, PROC "$select " "EXEC SQL select " "$insert " "EXEC SQL insert " "$update " "EXEC SQL update " "$delete " "EXEC SQL delete " "$prepare " "EXEC SQL prepare " "$declare " "EXEC SQL declare " "$open " "EXEC SQL open " "$fetch " "EXEC SQL fetch " "$close " "EXEC SQL close " "$free " "EXEC SQL free "或 "free_cursor()" "$begin work" "EXEC SQL begin work"或 "begin_work()" "$commit work" "EXEC SQL commit work" "$rollback work" "EXEC SQL rollback"或 "rollback_work()" "$database " "EXEC SQL database "或 "open_database()" 步骤 2,将剩下的‘$’全部替换成‘:’ 步骤 3,手工修改各数据库变量定义部分 步骤 4,将打开数据库语句更新成open_database() 步骤 5,编写相应的函数open_database(),free_cursor(),begin_work(),rollback_work()等,函数实体程序根据相应数据库平台的语法即可。 步骤 6,在公共头文件中宏定义#define SQLCODE sqlca.sqlcode 步骤 7,用PROC的makefile文件,进行重新编译,再细微调整错误的地方。   2.Makefile文件的编写 步骤 1,更改相应的编译变量 $(CC)也改成相应环境下的 C编译器 $(ECC)=xxx改成 $(PROC)=xxx 步骤 2,修改.ec到.o的编译方法 .ec.o:         $(PROC) $(INCLUDE) iname=$*.ec oname=$*.c         $(CC) -I$(INCLUDE) $(CFLAGS) -c -o $*.o $*.c         rm -f $*.c         rm -f $*.lis 步骤 3,修改连接方法 将 $(ECC)修改成$(CC)。   二.数据库移植 1.表结构的移植 软件工具 powdesinger 步骤 1,利用反向工程,从原来的INFORMIX数据库中生成PDM图表文件 步骤 2,更改当前数据库连接,新的连接为ORACLE数据库 步骤 3,生成SQL语句。 步骤 4,将该SQL语句在ORACLE环境中执行即可。   2.数据的移植 不同的数据库之间,采用文本文件移植较为安全 步骤 1,从INFORMIX库中导出所有表,可以用dbexport,也可以用shell文件执行unload to xx.txt select * from xx表 步骤 2,将文本文件传到可以导入ORACLE的位置。 步骤 3,编写ORACLE的sqlldr控制文件,执行即可。   第三部分:如何编写两个平台通用的C程序 在项目实施过程中,一个产品往往流程完全一致,但不同的客户可能数据库平台有区别,作为软件开发商或供应商,如果同时提供两个版本,很容易造成版本不统一,加大了维护成本,所以必须找到一个方法使两个版本程序能尽可能的复用。经过本人的实践,最后做出只需要修改一个宏定义,就可以实现程序在两个平台间的共用。   1.程序文件名的统一 ESQLC中只支持扩展名 =ec的ESQLC程序,而PROC中可支持任意扩展名的PROC程序,所以我们将程序名称统一成xxx.ec   2.数据库公共宏定义 /* #define DB_IS_INFORMIX */ #define DB_IS_ORACLE   #ifdef DB_IS_INFORMIX         #define SQL_DATA_FIND    0         #define SQL_NO_DATA_FIND 100 #else         #define SQL_DATA_FIND    0         #define SQL_NO_DATA_FIND 1403 #endif     3.部分数据库公共操作函数 EXEC SQL include sqlca;   //打开数据库 int open_database() {         EXEC SQL BEGIN DECLARE SECTION;         char username[50];         char password[50];         EXEC SQL END DECLARE SECTION;           memset(username, 0, sizeof(username));         memset(password, 0, sizeof(password));           strcpy(username, "数据库用户名");         strcpy(password, "数据库用户密码");   #ifdef DB_IS_INFORMIX         EXEC SQL database 数据库库名; #else         EXEC SQL connect :username identified by :password; #endif }   //开始事务 int begin_work() { #ifdef DB_IS_INFORMIX         EXEC SQL begin work;         if(sqlca.sqlcode){                 printf("begin_work error:%d/n", sqlca.sqlcode);                 return -1;         } else{                 return 0;         } #else                 return 0; #endif }   //回滚事务 int rollback_work() { #ifdef DB_IS_INFORMIX         EXEC SQL rollback work; #else         EXEC SQL rollback; #endif           if(sqlca.sqlcode){                 printf("rollback_work error:%d/n", sqlca.sqlcode);                 return -1;         } else{                 return 0;         } }   结束!    

    最新回复(0)