Linux下Oracle的Proc学习笔记

来源:互联网 发布:安妮宝贝知乎 编辑:程序博客网 时间:2024/05/21 18:36

Proc的make特别复杂,但是基本都一样,一个模板搞定所有

.SUFFIXES: .c .oCC=gccPROC=procPROCSRCS=oracle.pcSRCS=$(PROCSRCS:.pc=.c)OBJS=$(SRCS:.c=.o)ORACLE_HOME=/opt/oracle/product/11.2.0ORAFLAGS1=/usr/include/linuxORAFLAGS2=/usr/lib/gcc/x86_64-redhat-linux/4.4.4/includeEXE=abcall: $(OBJS)$(CC) -o $(EXE) $(OBJS) -L$(ORACLE_HOME)/lib -lclntsh@echo '^_^ ^_^ ^_^ ^_^ ^_^ ^_^ OK ^_^ ^_^ ^_^ ^_^ ^_^ ^_^'.c.o: $(SRCS)$(CC) -Wall -g -o $@ -c $<$(SRCS):$(PROC) INAME=$(PROCSRCS) INCLUDE=$(ORAFLAGS1) INCLUDE=$(ORAFLAGS2) CPOOL=YES MODE=ANSI CODE=ANSI_C PARSE=PARTIAL THREADS=YES ONAME=$(SRCS)clean:-rm -f $(OBJS)-rm -f $(SRCS)-rm -f core*

INAME        值是Filename  proc源文件名称

INCLUDE   值是Pathname proc去哪里找#include中包含的头文件

ONAME      值是Filrname预编译完成后输出文件名称

CPOOL       值是YES,NO 是否支持连接共享

MODE       值是ANSI,ISO,ORACLE代码对Oracle或ANSI规则的顺应性

CODE          值是ANSI_C,CPP,KR_C 所要生成的代码类型

PARSE        值是FULL,PARITIAL,NONE 控制对哪一非SQL代码进行语法分析

THREADS  值是YES,NO 是否支持多线程的应用程序

使用proc编程的步骤

-头文件包含和相关说明定义

-安装错误处理函数

-初始化数据库

-连接到数据库

-执行SQL语句

-断开连接

-释放相关资源


pc文件中如果在内嵌SQL语句中使用的变量,一定需要在EXEC SQL BEGIN DECLARE SECTION块语句中声明:

EXEC SQL BEGIN DECLARE SECTION;

sql_context pContext;

long SQLCODE;

EXEC SQL END DECLARE SECTION;


安装错误处理函数,这是Oracle下固定写法

extern void sqlglmt(void*, char*, size_t*, size_t*);void sql_error(){char sErrorString[512];size_t tMessageSize = 0;size_t tErrorSize = sizeof(sErrorString);memset(sErrorString, 0, sizeof(sErrorString));sqlglmt(pContext, sErrorString, &tErrorSize, &tMessageSize);// 调用这个函数得到具体错误描述sErrorString[tMessageSize] = 0;printf("%s\n", sErrorString);}

初始化数据库

void sql_init(){SQLCODE = 0;pContext = NULL;EXEC SQL ENABLE THREADS;EXEC SQL CONTEXT ALLOCATE :pContext;EXEC SQL CONTEXT USE :pContext;}


连接数据库

//初始化数据库
void sql_init()
{
SQLCODE = 0;
pContext = NULL;
EXEC SQL ENABLE THREADS;//可以在代码当中生成线程相关代码
EXEC SQL CONTEXT ALLOCATE :pContext;//为pContext分配内存
EXEC SQL CONTEXT USE :pContext;//使用pContext
}


执行sql语句

int sql_exec1();

int sql_exec2()

int sql_exec3()

int sql_exec4(const char *DySQL)


oracle标准使用例子,直接可以使用,Linux下

main.c

#include "oracle.h"int main(){sql_init();//初始化数据库sql_connect("dbuser1", "dbuser1", "orcl");//连接到oracle//sql_exec("insert into table1 (id, name) values (1, '测试')");//执行非SELECT的SQL语句sql_open("select * from table1");//执行SELECT SQL语句//sql_commit();//提交事务//sql_rollback();//回滚事务sql_disconnect();//断开连接sql_free();//释放资源return 0;}


oracle.h

#ifndef ORACLE_H_#define ORACLE_H_void sql_error();//打印错误信息void sql_init();//初始化oracleint sql_connect(const char *User, const char *Password, const char *DBName);//连接到oracleint sql_exec(const char *DySQL);//执行非select SQL语句int sql_commit();//提交事务int sql_rollback();//回滚事务int sql_open(const char *DySQL);//执行select SQL语句int sql_disconnect();//断开连接int sql_free();//释放资源#endif /* ORACLE_H_ */


oracle.pc

#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef __cplusplusextern "C"{#endifvoid sqlglmt(void*, char*, size_t*, size_t* ); #ifdef __cplusplus}#endif//嵌入式SQL中使用的变量,必须再EXEC SQL BEGIN DECLARE SECTION申明EXEC SQL BEGIN DECLARE SECTION; sql_context pContext;long SQLCODE;EXEC SQL END DECLARE SECTION;void sql_error()//打印错误信息{char sErrorString[512];//定义一个buf,存放错误描述size_t tMessageSize = 0;size_t tErrorSize = sizeof(sErrorString);memset(sErrorString, 0, sizeof(sErrorString));sqlglmt(pContext, sErrorString, &tErrorSize, &tMessageSize);//调用oracle的api函数得到错误信息sErrorString[tMessageSize] = 0;printf("%s\n", sErrorString);//打印错误信息}void sql_init()//初始化oracle{SQLCODE = 0;pContext = NULL;//如果proc的THREADS=YES,那么proc程序第一条嵌入SQL语句就应该是EXEC SQL ENABLE THREADSEXEC SQL ENABLE THREADS;//分配资源EXEC SQL CONTEXT ALLOCATE :pContext;//使用资源EXEC SQL CONTEXT USE :pContext;}int sql_connect(const char *User, const char *Password, const char *DBName)//连接到oracle{EXEC SQL BEGIN DECLARE SECTION;const char *sUser;const char *sPassword;const char *sServer;EXEC SQL END DECLARE SECTION;SQLCODE = 0;sUser = User;//连接oracle的用户名sPassword = Password;//连接oracle的密码sServer = DBName;//连接oracle的数据库名EXEC SQL CONNECT :sUser IDENTIFIED BY :sPassword USING :sServer;//连接到oracle的嵌入式SQLif (SQLCODE != 0)//如果SQLCODE != 0代表连接失败{sql_error();return 1;}else{return 0;}}int sql_exec(const char *DySQL)//执行非select SQL语句{EXEC SQL BEGIN DECLARE SECTION; const char *sDySQL;EXEC SQL END DECLARE SECTION;SQLCODE = 0;sDySQL = DySQL;EXEC SQL EXECUTE IMMEDIATE :sDySQL;//执行非select SQL语句if (SQLCODE != 0)//如果SQLCODE != 0代表执行失败{sql_error();return 1;}else{return 0;}}int sql_commit()//提交事务{SQLCODE = 0;EXEC SQL COMMIT WORK;if (SQLCODE != 0){sql_error();return 1;}else{return 0;}}int sql_rollback()//回滚事务{SQLCODE = 0;EXEC SQL ROLLBACK WORK;if (SQLCODE != 0){sql_error();return 1;}else{return 0;}}int sql_open(const char *DySQL)//执行select SQL语句{EXEC SQL BEGIN DECLARE SECTION;int i, iOutput_count, iOccurs, iType, iLen;short iInd;char sName[1024];//存放SELECT语句查询到的字段名char sData[1024];//存放SELECT语句查询到的字段值char sOutput[64];char sInput[64];const char *sDySQL;EXEC SQL END DECLARE SECTION;SQLCODE = 0;sDySQL = DySQL;sprintf(sOutput, "output%p", pContext);//格式化一个进程唯一不重复的字符串sprintf(sInput, "input%p", pContext);//格式化一个进程唯一不重复的字符串EXEC SQL ALLOCATE DESCRIPTOR :sOutput;//分配输出缓冲区EXEC SQL ALLOCATE DESCRIPTOR :sInput;//分配输入缓冲区EXEC SQL PREPARE S FROM :sDySQL;//准备执行sDySQL指定的SELECT语句if (SQLCODE != 0)//如果SQLCODE != 0代表执行失败{sql_error();EXEC SQL DEALLOCATE DESCRIPTOR :sInput;//释放输出缓冲区EXEC SQL DEALLOCATE DESCRIPTOR :sOutput;//释放输入缓冲区return 1;}EXEC SQL DECLARE C CURSOR FOR S;//申请一个游标,名为CEXEC SQL OPEN C USING DESCRIPTOR :sInput;//打开游标CEXEC SQL DESCRIBE OUTPUT S USING DESCRIPTOR :sOutput;//选择输出区域EXEC SQL GET DESCRIPTOR :sOutput :iOutput_count = COUNT;//取得选择列表的个数,放入变量iOutput_count当中for(i=0;i<iOutput_count;i++)//循环遍历字段,将所有字段名输出到屏幕{memset(sData, 0, sizeof(sData));memset(sName, 0, sizeof(sName));//得到SELECT语句查询返回的字段描述//sName中存放查询到的字段名,iType中存放字段类型,iLen中存放字段长度iOccurs = i + 1;//GET DESCRIPTOR语句中字段是从1开始的,所以iOccurs要从1开始执行EXEC SQL GET DESCRIPTOR :sOutputVALUE :iOccurs :iType = TYPE, :iLen = LENGTH, :sName = NAME;printf("%s\t", sName);//在屏幕打印字段名称iType = 12;//设置字段为字符串类型iLen = sizeof(sData);//设置接收字段返回值buffer最大长度为sizeof(sData)EXEC SQL SET DESCRIPTOR :sOutput VALUE :iOccurs TYPE = :iType, LENGTH = :iLen;}printf("\n");//字段名打印完毕,在屏幕上打印一个回车符EXEC SQL WHENEVER NOT FOUND DO BREAK;while(1)//循环遍历所有行,将行中所有字段值输出到屏幕{/*行数据,输出描述区*/ EXEC SQL FETCH C INTO DESCRIPTOR :sOutput;//得到一行记录for(i=0;i < iOutput_count;i++)//循环遍历一行记录中的每一个字段{iOccurs = i + 1;memset(sData, 0, sizeof(sData));iInd = 0;EXEC SQL GET DESCRIPTOR :sOutputVALUE :iOccurs :sData = DATA, :iInd = INDICATOR;if (iInd == -1)//如果字段中有NULL值,iInd == -1{printf("%s\t", "NULL");}else{printf("%s\t", sData);}}printf("\n");//一行记录打印完毕,在屏幕上打印一个回车符}EXEC SQL CLOSE C;//关闭游标CEXEC SQL DEALLOCATE DESCRIPTOR :sOutput;//释放输出缓冲区EXEC SQL DEALLOCATE DESCRIPTOR :sInput;//释放输入缓冲区return 0;}int sql_disconnect()//断开连接{SQLCODE = 0;EXEC SQL ROLLBACK WORK RELEASE;//断开连接,回滚事务//EXEC SQL COMMIT WORK RELEASE;//断开连接,提交事务if (SQLCODE != 0){sql_error();return 1;}else{return 0;}}int sql_free()//释放资源{SQLCODE = 0;EXEC SQL CONTEXT FREE :pContext;if (SQLCODE != 0){sql_error();return 1;}else{return 0;}}

makefile

.SUFFIXES: .c .oCC=gccPROC=procPROCSRCS=oracle.pcDBSRCS=$(PROCSRCS:.pc=.c)SRCS=main.c\$(DBSRCS)OBJS=$(SRCS:.c=.o)ORACLE_HOME=/opt/oracle/product/11.2.0ORAFLAGS1=/usr/include/linuxORAFLAGS2=/usr/lib/gcc/i686-redhat-linux/4.4.4/includeEXEC=myoracleall: $(OBJS)$(CC) -L${ORACLE_HOME}/lib -lclntsh -o $(EXEC) $(OBJS) @echo '^_^ ^_^ ^_^ ^_^ ^_^ ^_^ OK ^_^ ^_^ ^_^ ^_^ ^_^ ^_^'.c.o: $(DBSRCS)$(CC) -Wall -g -o $@ -c $<$(DBSRCS):$(PROC) INAME=$(PROCSRCS) INCLUDE=$(ORAFLAGS1) INCLUDE=$(ORAFLAGS2) CPOOL=YES MODE=ANSI CODE=ANSI_C PARSE=PARTIAL THREADS=YES ONAME=$(DBSRCS)clean:rm -f $(OBJS)rm -f $(DBSRCS)


这些嵌入式SQL经过Proc的翻译后会变成标准的c语句



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 安运继续教育的登录密码忘了怎么办 金蝶k3账套管理打不开了怎么办 仁和会计课堂app不能用怎么办 光大银行已经下卡了终审被拒怎么办 过了上诉期和申诉期该怎么办 北外大四学生要实习半年课程怎么办 电脑发给手机的文件过期了怎么办 农民给土地卖了30年后怎么办 家长发家长群作业太多老师怎么办 在考试中心补不了四级成绩怎么办 微信登录密码不记得了怎么办 欠农民工工资不给怎么办老板说没钱 国外期刊催问稿件不理睬怎么办 老公离不开老婆也离不开小三怎么办 出轨被老婆发现还和小三联系怎么办 老公出轨后回家老婆不想原谅怎么办 小三和原配打架都住院了怎么办 毕业太多年查不到学历认证怎么办 没有做税种核定开了票怎么办 在学信网上查不到学历信息怎么办 学信网手机号换了密码忘了怎么办 学信网手机号换了密码也忘了怎么办 学信网上学习形式是星号怎么办 新手机号已被注册微店买家怎么办 微信号被冻结了里面的钱怎么办 不懂公司产品却要接待老外怎么办 上菜时发现桌面摆不下新菜怎么办 超市买到过期产品商家不赔尝怎么办 皇帝成长计划2俘虏的士兵怎么办 晚上楼上有挪桌子的声音怎么办 金灶茶具出故障码e7怎么办 起亚k2灯泡掉进大灯总成怎么办 衣服上拆过线的针孔怎么办 驾考科目二坡道定点熄火怎么办 穿着超短裤感觉要漏屁股怎么办 台式电脑开机后无法进入系统怎么办 产后两年了肚子肥胖松弛怎么办 在作文中写上自己的名字怎么办 外出玩耍时迷路了你会怎么办 外出玩耍时孩子总喜欢乱跑怎么办? 如果真的物价高的受不了怎么办