开发者社区> 吴英强> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

【C/C++学院】(26)Oracle数据库编程--程序模板c/cpp

简介: <p>Makefile</p> <p></p> <pre code_snippet_id="627108" snippet_file_name="blog_20150324_1_7506775" name="code" class="cpp">.SUFFIXES: .c .o CC=gcc PROC=proc PROCSRCS=oracle.pc DBSRCS=$(PROCSRCS:
+关注继续查看

Makefile

.SUFFIXES: .c .o
CC=gcc
PROC=proc

PROCSRCS=oracle.pc
DBSRCS=$(PROCSRCS:.pc=.c)

SRCS=main.c\
	$(DBSRCS)
	
OBJS=$(SRCS:.c=.o)

ORACLE_HOME=/opt/oracle/product/11.2.0
ORAFLAGS1=/usr/include/linux
ORAFLAGS2=/usr/lib/gcc/i686-redhat-linux/4.4.4/include

EXEC=myoracle

all: $(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)

oracle.h

#ifndef ORACLE_H_
#define ORACLE_H_

void sql_error();//打印错误信息

void sql_init();//初始化oracle

int sql_connect(const char *User, const char *Password, const char *DBName);//连接到oracle

int 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  

涉及到具体逻辑的时候,只需要将printf的地方修改为逻辑处理

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __cplusplus
extern "C"
{
#endif
void 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 THREADS
	EXEC 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的嵌入式SQL
	if (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;//申请一个游标,名为C	
	EXEC SQL OPEN C USING DESCRIPTOR :sInput;//打开游标C
	
	EXEC 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 :sOutput
			VALUE :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 :sOutput
				VALUE :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;//关闭游标C
	EXEC 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;
	}
}

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;
}

如果更改为cpp, 修改makefile 文件

.SUFFIXES: .cpp .o
CC=g++
PROC=proc

PROCSRCS=oracle.pc
DBSRCS=$(PROCSRCS:.pc=.cpp)

SRCS=main.cpp\
	$(DBSRCS)
	
OBJS=$(SRCS:.cpp=.o)

ORACLE_HOME=/opt/oracle/product/11.2.0
ORAFLAGS1=/usr/include/linux
ORAFLAGS2=/usr/lib/gcc/i686-redhat-linux/4.4.4/include

EXEC=myoracle

all: $(OBJS)	
	$(CC) -L${ORACLE_HOME}/lib -lclntsh -o $(EXEC) $(OBJS) 	
	@echo '^_^ ^_^ ^_^ ^_^ ^_^ ^_^ OK ^_^ ^_^ ^_^ ^_^ ^_^ ^_^'

.cpp.o: $(DBSRCS)	
	$(CC) -Wall -g -o $@ -c $<

$(DBSRCS):	
	$(PROC) INAME=$(PROCSRCS) INCLUDE=$(ORAFLAGS1) INCLUDE=$(ORAFLAGS2) CPOOL=YES MODE=ANSI CODE=CPP PARSE=PARTIAL THREADS=YES ONAME=$(DBSRCS)

clean:
	rm -f $(OBJS)	
	rm -f $(DBSRCS)





版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
C++ 操作 Oracle
#include <string> #include <occi.h> #include <iostream> using namespace std; using namespace oracle::occi; struct Student_struct { int no; int age; string name; }; std
849 0
Oracle 数据库性能优化3日实战(企业培训)
课程名称一: Oracle性能优化及调整 课程时长 1天 课程深度: 高级 上机实验: 10%-30% 授课对象: Oracle开发人员、Oracle数据库管理人员,应用程序开发人员 课程描述: 本课程讲述Oracle数据库物理层规划,系统性能的监控,数据库性能参数调整,统计信息的收集,使用自动化调试工具优化数据库,I/O子系统的配置与设计以及性能优化方法论等。
1820 0
如何连接别人电脑上的ORACLE数据库
如何连接别人电脑上的ORACLE数据库 (以oracle9i版本为例,本机必须安装oralce9i的客户端) 第一步:orahome92-configuration and migration tools- net managers 第二步:在“服...
882 0
[20141024]使用emacs连接使用oracle数据库
[20141024]使用emacs连接使用oracle数据库.txt --前一阵子跟别人学习了使用emacs连接数据库.自己做一个简单记录. 1.首先需要安装emacs.
935 0
+关注
329
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载