zoukankan      html  css  js  c++  java
  • 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
    ", 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	", "NULL");
                }
                else
                {
                    printf("%s	", sData);
                }
            }
            printf("
    ");
        }
    执行一个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;
    }
     
  • 相关阅读:
    PCL:描述三维离散点的ROPS特征(Code)
    veket智能机器人
    三维重建:SLAM的粒度和工程化问题
    DNN:逻辑回归与 SoftMax 回归方法
    人工智能:一种现代方法 第四版 翻译序言
    编程低级错误记录
    apache服务器配置防盗链(centos7)
    Linux下命令行中的复制和粘贴
    rm: cannot remove `libtoolT’: No such file or directory
    switch范围判断
  • 原文地址:https://www.cnblogs.com/shichuan/p/4497859.html
Copyright © 2011-2022 走看看