PROC程序设计

通过在过程化编程语言中嵌入SQL语句而开发出的应用程序称为Pro程序。
在C/C++语言中嵌入SQL语句而开发出的应用程序称为Pro*C/C++程序。
  –在通用编程语言中使用的SQL称为嵌入式SQL;
  –在SQL标准中定义了多种语言的嵌入式SQL。
 
 

宿主语言     Pro程序

C/C++            Pro*C/C++

FORTRAN          Pro*FORTRAN

PASCAL           Pro*PASCAL

COBOL            Pro*COBOL

 

 

ProC/C++预编译程序
  –完成pc源程序到c/c++源程序的转换。
基本命令格式

  PROC INAME=filename [OptionName1=value1]…[OptionNameN=valueN]

 

proc常用选项说明

选项

说明

INAME

Filename

proc源文件名称

INCLUDE

Pathname

指示proc去哪里找#include中包含的头文件

ONAME

Filename

预编译完成后输出文件名称

CPOOL

YES,NO

是否支持连接共享

MODE

ANSI,ISO,ORACLE

代码对 Oracle 或 ANSI 规则的顺应性

CODE

ANSI_C,CPP,KR_C

所要生成的代码类型

PARSE

FULL,PARITIAL,NONE

控制对哪一 非 SQL 代码进行语法分析

THREADS

YES,NO

是否支持多线程的应用程序

–在命令行输入不带选项的proc命令就可以列出所有选项以及当前默认值
–proc 选项=?就可以查看选项说明
 
gcc或者g++链接时需要增加

-L${ORACLE_HOME}/lib –lclntsh

指示编译器需要链接相关的库文件

开发之前先写一个适合proc使用的makefile
 
 
 
首先定义几个常量
.SUFFIXES: .c .o
CC=gcc
PROC=proc

PROCSRCS=oracle.pc
SRCS=$(PROCSRCS:.pc=.c)
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=abc
all: $(OBJS)    
    $(CC) -L${ORACLE_HOME}/lib -lclntsh -o $(EXEC) $(OBJS)     
    @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)
 
使用proc编程步骤
  –头文件包含和相关说明定义;
  –安装错误处理函数;
  –初始化数据库;
  –连接到数据库;
  –执行SQL语句;
  –断开连接;
  –释放相关资源。
 
pc文件的编写
首先包含三个最基本的头文件

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

 

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

EXEC SQL BEGIN DECLARE SECTION;

  sql_context pContext;

  long SQLCODE;

EXEC SQL END DECLARE SECTION;

 

安装错误处理函数:
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;
}

 

连接到数据库:
int sql_connect(const char *User, const char *Password, const char *DBName)
{
    EXEC SQL BEGIN DECLARE SECTION;
        const char *sUser;
        const char *sPassword;
        const char *sServer;
    EXEC SQL END DECLARE SECTION;
    SQLCODE = 0; sUser = User; sPassword = Password; sServer = DBName;
    EXEC SQL CONNECT :sUser IDENTIFIED BY :sPassword USING :sServer;
    if (SQLCODE != 0)
    {
        sql_error();
        return 1;
    }else
        return 0;
}

 

执行一个非SELECT SQL语句:
int sql_exec(const char *DySQL)
{
    EXEC SQL BEGIN DECLARE SECTION; 
        const char *sDySQL;
    EXEC SQL END DECLARE SECTION;
    
    SQLCODE = 0;
    sDySQL = DySQL;
    EXEC SQL EXECUTE IMMEDIATE :sDySQL;
    if (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;
    }
}

 

 

 

执行一个SELECT语句,并查看返回结果(一):
int sql_open(const char *DySQL)
{
    EXEC SQL BEGIN DECLARE SECTION;
        int i, iOutput_count, iOccurs, iType, iLen;
        short iInd;
        char sData[1024];//result buffer;
        char sOutput[64];
        char sInput[64];
        const char *sDySQL;
    EXEC SQL END DECLARE SECTION;

 

 

 

执行一个SELECT语句,并查看返回结果(二):
    SQLCODE = 0;
    iLen = sizeof(sData);
    iType = 12;//set type is varchar;
    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;

 

 

 

执行一个SELECT语句,并查看返回结果(三):
    if (SQLCODE != 0)
    {
        sql_error();
        EXEC SQL DEALLOCATE DESCRIPTOR :sInput;
        EXEC SQL DEALLOCATE DESCRIPTOR :sOutput;
        return 1;        
    }

 

 

执行一个SELECT语句,并查看返回结果(四):
    EXEC SQL DECLARE C CURSOR FOR S;    
    EXEC SQL OPEN C USING DESCRIPTOR :sInput;
    /*选择输出区域*/
    EXEC SQL DESCRIBE OUTPUT S USING DESCRIPTOR :sOutput;
    /*取得选择列表的个数*/
    EXEC SQL GET DESCRIPTOR :sOutput :iOutput_count = COUNT;
    for(i=0;i<iOutput_count;i++)
    {
        iOccurs = i + 1;    
        EXEC SQL SET DESCRIPTOR :sOutput 
            VALUE :iOccurs TYPE = :iType, LENGTH = :iLen;            
    }

 

 

执行一个SELECT语句,并查看返回结果(五):
    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)
            {
                printf("%s\t", "NULL");
            }
            else
            {
                printf("%s\t", sData);
            }
        }
        printf("\n");
    }

 

 

 

执行一个SELECT语句,并查看返回结果(六):
    EXEC SQL CLOSE C;
    EXEC SQL DEALLOCATE DESCRIPTOR :sOutput;
    EXEC SQL DEALLOCATE DESCRIPTOR :sInput;
    return 0;
}

 

断开连接:
int sql_disconnect()
{
    SQLCODE = 0;
    EXEC SQL ROLLBACK 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函数调用的例子:
int main()
{
    sql_init();
    sql_connect("dbuser1", "dbuser1", "orcl");    
    sql_open("select * from baidu");
    //sql_commit();
    sql_disconnect();
    sql_free();
    return 0;
}

 

 
posted @ 2015-05-12 16:53  张仕传  阅读(514)  评论(0编辑  收藏  举报