Archive for the ‘Pro*C’ Category

  1. Hello, Pro*C/C++ World!

    Posted on 4月 1st, 2012 by cx20

    Pro*C/C++

    Pro*C/C++ は Oracle Database に対応した C/C++ 用の埋め込み SQL(Embedded SQL)である。類似の製品としては、Pro*COBOL、Pro*FORTRAN、Pro*Pascal 等がある。Pro*C/C++ は、UNIX 環境で C/C++ を用いた開発に使用されることが多い。
    なお、埋め込み SQL 自体は、標準SQL として ANSI/ISO にて仕様が策定されている。

    ソースコード

    #include <stdio.h>
     
    EXEC SQL INCLUDE SQLCA;
     
    int main( int argc, char* argv[] )
    {
        EXEC SQL BEGIN DECLARE SECTION;
        char username[] = "scott";
        char password[] = "tiger";
        char message[32];
        EXEC SQL END DECLARE SECTION;
        EXEC SQL CONNECT :username IDENTIFIED BY :password;
        EXEC SQL DECLARE C1 CURSOR FOR
            SELECT 'Hello, Pro*C/C++ World!' AS Message FROM DUAL;
        EXEC SQL OPEN C1;
        EXEC SQL WHENEVER NOT FOUND DO BREAK;
        for (;;)
        {
            EXEC SQL FETCH C1 INTO :message;
            printf("Messagen");
            printf("-----------------------n");
            printf("%sn", message);
        }
        EXEC SQL CLOSE C1;
        EXEC SQL COMMIT RELEASE;
        return 0;
    }

    上記コードは、proc プリプロセッサにより、以下の C言語のコードが生成される。

    ソースコード

    /* Result Sets Interface */
    #ifndef SQL_CRSR
    #  define SQL_CRSR
      struct sql_cursor
      {
        unsigned int curocn;
        void *ptr1;
        void *ptr2;
        unsigned int magic;
      };
      typedef struct sql_cursor sql_cursor;
      typedef struct sql_cursor SQL_CURSOR;
    #endif /* SQL_CRSR */
    /* Thread Safety */
    typedef void * sql_context;
    typedef void * SQL_CONTEXT;
    /* Object support */
    struct sqltvn
    {
      unsigned char *tvnvsn; 
      unsigned short tvnvsnl; 
      unsigned char *tvnnm;
      unsigned short tvnnml; 
      unsigned char *tvnsnm;
      unsigned short tvnsnml;
    };
    typedef struct sqltvn sqltvn;
    struct sqladts
    {
      unsigned int adtvsn; 
      unsigned short adtmode; 
      unsigned short adtnum;  
      sqltvn adttvn[1];       
    };
    typedef struct sqladts sqladts;
    static struct sqladts sqladt = {
      1,1,0,
    };
    /* Binding to PL/SQL Records */
    struct sqltdss
    {
      unsigned int tdsvsn; 
      unsigned short tdsnum; 
      unsigned char *tdsval[1]; 
    };
    typedef struct sqltdss sqltdss;
    static struct sqltdss sqltds =
    {
      1,
      0,
    };
    /* File name & Package Name */
    struct sqlcxp
    {
      unsigned short fillen;
               char  filnam[9];
    };
    static const struct sqlcxp sqlfpn =
    {
        8,
        "hello.pc"
    };
    static unsigned int sqlctx = 18323;
    static struct sqlexd {
       unsigned int   sqlvsn;
       unsigned int   arrsiz;
       unsigned int   iters;
       unsigned int   offset;
       unsigned short selerr;
       unsigned short sqlety;
       unsigned int   occurs;
          const short *cud;
       unsigned char  *sqlest;
          const char  *stmt;
       sqladts *sqladtp;
       sqltdss *sqltdsp;
                void  **sqphsv;
       unsigned int   *sqphsl;
                int   *sqphss;
                void  **sqpind;
                int   *sqpins;
       unsigned int   *sqparm;
       unsigned int   **sqparc;
       unsigned short  *sqpadto;
       unsigned short  *sqptdso;
       unsigned int   sqlcmax;
       unsigned int   sqlcmin;
       unsigned int   sqlcincr;
       unsigned int   sqlctimeout;
       unsigned int   sqlcnowait;
                  int   sqfoff;
       unsigned int   sqcmod;
       unsigned int   sqfmod;
                void  *sqhstv[4];
       unsigned int   sqhstl[4];
                int   sqhsts[4];
                void  *sqindv[4];
                int   sqinds[4];
       unsigned int   sqharm[4];
       unsigned int   *sqharc[4];
       unsigned short  sqadto[4];
       unsigned short  sqtdso[4];
    } sqlstm = {12,4};
    /* SQLLIB Prototypes */
    extern void sqlcxt (void **, unsigned int *,
                        struct sqlexd *, const struct sqlcxp *);
    extern void sqlcx2t(void **, unsigned int *,
                        struct sqlexd *, const struct sqlcxp *);
    extern void sqlbuft(void **, char *);
    extern void sqlgs2t(void **, char *);
    extern void sqlorat(void **, unsigned int *, void *);
    /* Forms Interface */
    static const int IAPSUCC = 0;
    static const int IAPFAIL = 1403;
    static const int IAPFTL  = 535;
    extern void sqliem(unsigned char *, signed int *);
     static const char *sq0002 = 
    "select 'Hello, Pro*C World!' Message  from DUAL            ";
    typedef struct { unsigned short len; unsigned char arr[1]; } VARCHAR;
    typedef struct { unsigned short len; unsigned char arr[1]; } varchar;
    /* cud (compilation unit data) array */
    static const short sqlcud0[] =
    {12,4130,838,0,0,
    5,0,0,0,0,0,27,12,0,0,4,4,0,1,0,1,97,0,0,1,97,0,0,1,10,0,0,1,10,0,0,
    36,0,0,2,59,0,9,15,0,0,0,0,0,1,0,
    51,0,0,2,0,0,13,19,0,0,1,0,0,1,0,2,97,0,0,
    70,0,0,2,0,0,15,24,0,0,0,0,0,1,0,
    85,0,0,3,0,0,30,25,0,0,0,0,0,1,0,
    };
    #include <stdio.h>
    /* EXEC SQL INCLUDE SQLCA;
     */ 
     
    #ifndef SQLCA
    #define SQLCA 1
     
    struct   sqlca
             {
             /* ub1 */ char    sqlcaid[8];
             /* b4  */ int     sqlabc;
             /* b4  */ int     sqlcode;
             struct
               {
               /* ub2 */ unsigned short sqlerrml;
               /* ub1 */ char           sqlerrmc[70];
               } sqlerrm;
             /* ub1 */ char    sqlerrp[8];
             /* b4  */ int     sqlerrd[6];
             /* ub1 */ char    sqlwarn[8];
             /* ub1 */ char    sqlext[8];
             };
    #ifndef SQLCA_NONE 
    #ifdef   SQLCA_STORAGE_CLASS
    SQLCA_STORAGE_CLASS struct sqlca sqlca
    #else
             struct sqlca sqlca
    #endif
     
    #ifdef  SQLCA_INIT
             = {
             {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
             sizeof(struct sqlca),
             0,
             { 0, {0}},
             {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
             {0, 0, 0, 0, 0, 0},
             {0, 0, 0, 0, 0, 0, 0, 0},
             {0, 0, 0, 0, 0, 0, 0, 0}
             }
    #endif
             ;
    #endif
     
    #endif
     
    /* end SQLCA */
    int main( int argc, char* argv[] )
    {
        /* EXEC SQL BEGIN DECLARE SECTION; */ 
        char username[] = "scott";
        char password[] = "tiger";
        char message[32];
        /* EXEC SQL END DECLARE SECTION; */ 
        /* EXEC SQL CONNECT :username IDENTIFIED BY :password; */ 
    {
        struct sqlexd sqlstm;
        sqlstm.sqlvsn = 12;
        sqlstm.arrsiz = 4;
        sqlstm.sqladtp = &sqladt;
        sqlstm.sqltdsp = &sqltds;
        sqlstm.iters = (unsigned int  )10;
        sqlstm.offset = (unsigned int  )5;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlstm.sqhstv[0] = (         void  *)username;
        sqlstm.sqhstl[0] = (unsigned int  )0;
        sqlstm.sqhsts[0] = (         int  )0;
        sqlstm.sqindv[0] = (         void  *)0;
        sqlstm.sqinds[0] = (         int  )0;
        sqlstm.sqharm[0] = (unsigned int  )0;
        sqlstm.sqadto[0] = (unsigned short )0;
        sqlstm.sqtdso[0] = (unsigned short )0;
        sqlstm.sqhstv[1] = (         void  *)password;
        sqlstm.sqhstl[1] = (unsigned int  )0;
        sqlstm.sqhsts[1] = (         int  )0;
        sqlstm.sqindv[1] = (         void  *)0;
        sqlstm.sqinds[1] = (         int  )0;
        sqlstm.sqharm[1] = (unsigned int  )0;
        sqlstm.sqadto[1] = (unsigned short )0;
        sqlstm.sqtdso[1] = (unsigned short )0;
        sqlstm.sqphsv = sqlstm.sqhstv;
        sqlstm.sqphsl = sqlstm.sqhstl;
        sqlstm.sqphss = sqlstm.sqhsts;
        sqlstm.sqpind = sqlstm.sqindv;
        sqlstm.sqpins = sqlstm.sqinds;
        sqlstm.sqparm = sqlstm.sqharm;
        sqlstm.sqparc = sqlstm.sqharc;
        sqlstm.sqpadto = sqlstm.sqadto;
        sqlstm.sqptdso = sqlstm.sqtdso;
        sqlstm.sqlcmax = (unsigned int )100;
        sqlstm.sqlcmin = (unsigned int )2;
        sqlstm.sqlcincr = (unsigned int )1;
        sqlstm.sqlctimeout = (unsigned int )0;
        sqlstm.sqlcnowait = (unsigned int )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
        /* EXEC SQL DECLARE C1 CURSOR FOR
            SELECT 'Hello, Pro*C/C++ World!' AS Message FROM DUAL; */ 
        /* EXEC SQL OPEN C1; */ 
    {
        struct sqlexd sqlstm;
        sqlstm.sqlvsn = 12;
        sqlstm.arrsiz = 4;
        sqlstm.sqladtp = &sqladt;
        sqlstm.sqltdsp = &sqltds;
        sqlstm.stmt = sq0002;
        sqlstm.iters = (unsigned int  )1;
        sqlstm.offset = (unsigned int  )36;
        sqlstm.selerr = (unsigned short)1;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlstm.sqcmod = (unsigned int )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
        /* EXEC SQL WHENEVER NOT FOUND DO BREAK; */ 
        for (;;)
        {
            /* EXEC SQL FETCH C1 INTO :message; */ 
    {
            struct sqlexd sqlstm;
            sqlstm.sqlvsn = 12;
            sqlstm.arrsiz = 4;
            sqlstm.sqladtp = &sqladt;
            sqlstm.sqltdsp = &sqltds;
            sqlstm.iters = (unsigned int  )1;
            sqlstm.offset = (unsigned int  )51;
            sqlstm.selerr = (unsigned short)1;
            sqlstm.cud = sqlcud0;
            sqlstm.sqlest = (unsigned char  *)&sqlca;
            sqlstm.sqlety = (unsigned short)4352;
            sqlstm.occurs = (unsigned int  )0;
            sqlstm.sqfoff = (           int )0;
            sqlstm.sqfmod = (unsigned int )2;
            sqlstm.sqhstv[0] = (         void  *)message;
            sqlstm.sqhstl[0] = (unsigned int  )32;
            sqlstm.sqhsts[0] = (         int  )0;
            sqlstm.sqindv[0] = (         void  *)0;
            sqlstm.sqinds[0] = (         int  )0;
            sqlstm.sqharm[0] = (unsigned int  )0;
            sqlstm.sqadto[0] = (unsigned short )0;
            sqlstm.sqtdso[0] = (unsigned short )0;
            sqlstm.sqphsv = sqlstm.sqhstv;
            sqlstm.sqphsl = sqlstm.sqhstl;
            sqlstm.sqphss = sqlstm.sqhsts;
            sqlstm.sqpind = sqlstm.sqindv;
            sqlstm.sqpins = sqlstm.sqinds;
            sqlstm.sqparm = sqlstm.sqharm;
            sqlstm.sqparc = sqlstm.sqharc;
            sqlstm.sqpadto = sqlstm.sqadto;
            sqlstm.sqptdso = sqlstm.sqtdso;
            sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
            if (sqlca.sqlcode == 1403) break;
    }
            printf("Messagen");
            printf("-----------------------n");
            printf("%sn", message);
        }
        /* EXEC SQL CLOSE C1; */ 
    {
        struct sqlexd sqlstm;
        sqlstm.sqlvsn = 12;
        sqlstm.arrsiz = 4;
        sqlstm.sqladtp = &sqladt;
        sqlstm.sqltdsp = &sqltds;
        sqlstm.iters = (unsigned int  )1;
        sqlstm.offset = (unsigned int  )70;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
        /* EXEC SQL COMMIT RELEASE; */ 
    {
        struct sqlexd sqlstm;
        sqlstm.sqlvsn = 12;
        sqlstm.arrsiz = 4;
        sqlstm.sqladtp = &sqladt;
        sqlstm.sqltdsp = &sqltds;
        sqlstm.iters = (unsigned int  )1;
        sqlstm.offset = (unsigned int  )85;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
        return 0;
    }

    コンパイル&リンク方法(Visual C++)

    C:¥> SET PATH=ORACLE_BASEORACLE_HOMEbin;%PATH%
    C:¥> SET INCLUDE=ORACLE_BASEORACLE_HOMEprecomppublic;%INCLUDE%
    C:¥> SET LIB=ORACLE_BASEORACLE_HOMEprecomplib;%LIB%
    C:¥> proc hello.pc
    C:¥> cl hello.c /link orasql11.lib

    実行結果

    Message
    -----------------------
    Hello, Pro*C/C++ World!