Proc程序设计-

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

 

 

 

 

proc编程
嵌入式sql:sql写入到C语言程序中

proc编程头文件路径
app\xxx\product\11.2.0\dbhome_1\precomp\public

proc编程要注意proc编译器也会使用gcc编译器中的头文件,所以需要在proc编译器中进行配置,加上系统的头文件路径
配置文件路径是:app\xxx\product\11.2.0\dbhome_1\precomp\admin\pcscfg.cfg


proc开发流程

1.proc工具预编译 *.pc==>.c
proc编译选项:parse=full|none(default full for C,others for c++) code=ANSI_C|CPP(default ansi_c)
C语言编译:proc 源文件 生成文件
c++编译:proc  源文件 生成文件 parse=none code=cpp
2.linux下编译gcc -o dm01_hello dm01_hello.c -I/home/oracle_11/app/oracle/product/11.2.0/db_1/precomp/public \
    -L/home/oracle_11/app/oracle/product/11.2.0/db_1/lib  -lclntsh
--linux查看oracle错误码:oerr ora 错误码
3.执行应用程序

proc程序结构
include 头文件(c/c++ and pro*c/c++)
定义变量
定义函数
main
    连接数据库:connect
    SQL操作语句:EXEC SQL...
    处理异常:exception handler
    断开连接:EXEC SQL COMMIT.ROLLBACK WORK release

 

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

//先定义宿主变量(SQL变量)
EXEC SQL BEGIN DECLARE SECTION;
    char * serverid="scott/123456";
EXEC SQL END DECLARE SECTION;

void main()
{
    int ret=0;
    //C语言中使用宿主变量
    printf("serverid=%s\r\n",serverid);
    //连接数据库
    EXEC SQL connect:serverid;
    if(sqlca.sqlcode!=0)
    {
        ret=sqlca.sqlcode;
        printf("connect err :%d",ret);
        system("pause");
    }
    printf("connect ok!\r\n");
    //提交事务断开连接
    EXEC SQL commit release;
    printf("Oracle closed !\r\n");
    system("pause");
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值