本帖最后由 iw1210 于 2013-01-06 13:21:41 编辑

解决方案 »

  1.   

    看两种定义展开成C代码后的区别:
    第一种定义链接数据库的用户名和密码:#define     LEN        40
    VARCHAR     username[LEN];  
    varchar     password[LEN];   strncpy((char *) username.arr, "SCOTT", LEN);
    username.len = (unsigned short) strlen((char *) username.arr);strncpy((char *) password.arr, "TIGER", LEN);
    password.len = (unsigned short) strlen((char *) password.arr);EXEC SQL CONNECT :username IDENTIFIED BY :password; // 这句预编译后的C代码:{
    ...
        sqlstm.sqhstv[0] = (unsigned char  *)&username;
        sqlstm.sqhstl[0] = (unsigned long )42;
        sqlstm.sqhsts[0] = (         int  )42;
    ...    sqlstm.sqhstv[1] = (unsigned char  *)&password;
        sqlstm.sqhstl[1] = (unsigned long )42;
        sqlstm.sqhsts[1] = (         int  )42;
    ...
    }第二种定义链接数据库的用户名和密码:#define     LEN        40typedef char asciiz[LEN]; 
    asciiz     username; 
    asciiz     password; strcpy(username, "SCOTT"); 
    strcpy(password, "TIGER"); EXEC SQL CONNECT :username IDENTIFIED BY :password; // 这句预编译后的C代码:
    {
    ...
        sqlstm.sqhstv[0] = (unsigned char  *)username;
        sqlstm.sqhstl[0] = (unsigned long )40;
        sqlstm.sqhsts[0] = (         int  )40;
    ...
        sqlstm.sqhstv[1] = (unsigned char  *)password;
        sqlstm.sqhstl[1] = (unsigned long )40;
        sqlstm.sqhsts[1] = (         int  )40;
    ...
    }
      

  2.   

    第一种 VARCHAR  类型的定义是怎么样的?C里面没这个类型的
      

  3.   

    两种定义的.pc文件代码:#include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sqlda.h>
    #include <sqlcpr.h>
    #define     LEN        40VARCHAR     username[LEN];  
    varchar     password[LEN];   void sql_error(msg) 
        char *msg;

        char err_msg[512];
        size_t buf_len, msg_len;    EXEC SQL WHENEVER SQLERROR CONTINUE;    printf("\n%s\n", msg);/* Call sqlglm() to get the complete text of the
     * error message.
     */
        buf_len = sizeof (err_msg);
        sqlglm(err_msg, &buf_len, &msg_len);
        printf("%.*s\n", msg_len, err_msg);    EXEC SQL ROLLBACK RELEASE;
        exit(EXIT_FAILURE);
    } void main()
    {
        strncpy((char *) username.arr, "SCOTT", LEN);
        username.len = 
          (unsigned short) strlen((char *) username.arr);    strncpy((char *) password.arr, "TIGER", LEN);
        password.len = 
          (unsigned short) strlen((char *) password.arr);   EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--");/* Connect to ORACLE. */
        EXEC SQL CONNECT :username IDENTIFIED BY :password;    printf("\nConnected to ORACLE as user: %s\n", username.arr);/* Disconnect from ORACLE. */
        EXEC SQL ROLLBACK WORK RELEASE;
        exit(EXIT_SUCCESS);
    }#include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sqlda.h>
    #include <sqlcpr.h>
    #define     LEN        40typedef char asciiz[LEN]; 
    asciiz     username; 
    asciiz     password;    void sql_error(msg) 
        char *msg;

        char err_msg[512];
        size_t buf_len, msg_len;    EXEC SQL WHENEVER SQLERROR CONTINUE;    printf("\n%s\n", msg);/* Call sqlglm() to get the complete text of the
     * error message.
     */
        buf_len = sizeof (err_msg);
        sqlglm(err_msg, &buf_len, &msg_len);
        printf("%.*s\n", msg_len, err_msg);    EXEC SQL ROLLBACK RELEASE;
        exit(EXIT_FAILURE);
    } void main()
    {
        strcpy(username, "SCOTT"); 
        strcpy(password, "TIGER");     EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--");/* Connect to ORACLE. */
        EXEC SQL CONNECT :username IDENTIFIED BY :password;    printf("\nConnected to ORACLE as user: %s\n", username); /* Disconnect from ORACLE. */
        EXEC SQL ROLLBACK WORK RELEASE;
        exit(EXIT_SUCCESS);
    }
      

  4.   

    还是没看到VARCHAR类型是如何定义的
      

  5.   

    回复 5 楼 edcvf3额,你不会是不会用proc预编译吧
      

  6.   

    没用过PROC ,用过C,知道头文件里应该有类型定义,可惜你不给看啊
      

  7.   


    好吧,我把两个预编译后的.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 struct sqlcxp sqlfpn =
    {
        8,
        "test1.pc"
    };
    static unsigned int sqlctx = 19971;
    static struct sqlexd {
       unsigned long  sqlvsn;
       unsigned int   arrsiz;
       unsigned int   iters;
       unsigned int   offset;
       unsigned short selerr;
       unsigned short sqlety;
       unsigned int   occurs;
                short *cud;
       unsigned char  *sqlest;
                char  *stmt;
       sqladts *sqladtp;
       sqltdss *sqltdsp;
       unsigned char  **sqphsv;
       unsigned long  *sqphsl;
                int   *sqphss;
                short **sqpind;
                int   *sqpins;
       unsigned long  *sqparm;
       unsigned long  **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;
       unsigned char  *sqhstv[4];
       unsigned long  sqhstl[4];
                int   sqhsts[4];
                short *sqindv[4];
                int   sqinds[4];
       unsigned long  sqharm[4];
       unsigned long  *sqharc[4];
       unsigned short  sqadto[4];
       unsigned short  sqtdso[4];
    } sqlstm = {12,4};/* SQLLIB Prototypes */
    extern sqlcxt ( void **, unsigned int *,
                       struct sqlexd *, struct sqlcxp * );
    extern sqlcx2t( void **, unsigned int *,
                       struct sqlexd *, struct sqlcxp * );
    extern sqlbuft( void **, char * );
    extern sqlgs2t( void **, char * );
    extern sqlorat( void **, unsigned int *, void * );/* Forms Interface */
    static int IAPSUCC = 0;
    static int IAPFAIL = 1403;
    static int IAPFTL  = 535;
    extern void sqliem( unsigned char *, signed int * );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 short sqlcud0[] =
    {12,4130,1,0,0,
    5,0,0,1,0,0,32,31,0,0,0,0,0,1,0,
    20,0,0,0,0,0,27,48,0,0,4,4,0,1,0,1,9,0,0,1,9,0,0,1,10,0,0,1,10,0,0,
    51,0,0,3,0,0,32,53,0,0,0,0,0,1,0,
    };#include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sqlda.h>
    #include <sqlcpr.h>
    #define     LEN        40/* VARCHAR     username[LEN]; */ 
    struct { unsigned short len; unsigned char arr[40]; } username;
      
    /* varchar     password[LEN]; */ 
    struct { unsigned short len; unsigned char arr[40]; } password;
       void sql_error(msg) 
        char *msg;

        char err_msg[512];
        size_t buf_len, msg_len;    /* EXEC SQL WHENEVER SQLERROR CONTINUE; */ 
        printf("\n%s\n", msg);/* Call sqlglm() to get the complete text of the
     * error message.
     */
        buf_len = sizeof (err_msg);
        sqlglm(err_msg, &buf_len, &msg_len);
        printf("%.*s\n", msg_len, err_msg);    /* EXEC SQL ROLLBACK RELEASE; */ {
        struct sqlexd sqlstm;
        sqlstm.sqlvsn = 12;
        sqlstm.arrsiz = 0;
        sqlstm.sqladtp = &sqladt;
        sqlstm.sqltdsp = &sqltds;
        sqlstm.iters = (unsigned int  )1;
        sqlstm.offset = (unsigned int  )5;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
        exit(EXIT_FAILURE);
    } void main()
    {
        strncpy((char *) username.arr, "SCOTT", LEN);
        username.len = 
          (unsigned short) strlen((char *) username.arr);    strncpy((char *) password.arr, "TIGER", LEN);
        password.len = 
          (unsigned short) strlen((char *) password.arr);   /* EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--"); */ 
    /* Connect to ORACLE. */
        /* 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  )20;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlstm.sqhstv[0] = (unsigned char  *)&username;
        sqlstm.sqhstl[0] = (unsigned long )42;
        sqlstm.sqhsts[0] = (         int  )42;
        sqlstm.sqindv[0] = (         short *)0;
        sqlstm.sqinds[0] = (         int  )0;
        sqlstm.sqharm[0] = (unsigned long )0;
        sqlstm.sqadto[0] = (unsigned short )0;
        sqlstm.sqtdso[0] = (unsigned short )0;
        sqlstm.sqhstv[1] = (unsigned char  *)&password;
        sqlstm.sqhstl[1] = (unsigned long )42;
        sqlstm.sqhsts[1] = (         int  )42;
        sqlstm.sqindv[1] = (         short *)0;
        sqlstm.sqinds[1] = (         int  )0;
        sqlstm.sqharm[1] = (unsigned long )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);
        if (sqlca.sqlcode < 0) sql_error("ORACLE error--");
    }    printf("\nConnected to ORACLE as user: %s\n", username.arr);/* Disconnect from ORACLE. */
        /* EXEC SQL ROLLBACK WORK 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  )51;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
        if (sqlca.sqlcode < 0) sql_error("ORACLE error--");
    }
        exit(EXIT_SUCCESS);
    }
      

  8.   


    /* 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 struct sqlcxp sqlfpn =
    {
        8,
        "test2.pc"
    };
    static unsigned int sqlctx = 19979;
    static struct sqlexd {
       unsigned long  sqlvsn;
       unsigned int   arrsiz;
       unsigned int   iters;
       unsigned int   offset;
       unsigned short selerr;
       unsigned short sqlety;
       unsigned int   occurs;
                short *cud;
       unsigned char  *sqlest;
                char  *stmt;
       sqladts *sqladtp;
       sqltdss *sqltdsp;
       unsigned char  **sqphsv;
       unsigned long  *sqphsl;
                int   *sqphss;
                short **sqpind;
                int   *sqpins;
       unsigned long  *sqparm;
       unsigned long  **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;
       unsigned char  *sqhstv[4];
       unsigned long  sqhstl[4];
                int   sqhsts[4];
                short *sqindv[4];
                int   sqinds[4];
       unsigned long  sqharm[4];
       unsigned long  *sqharc[4];
       unsigned short  sqadto[4];
       unsigned short  sqtdso[4];
    } sqlstm = {12,4};/* SQLLIB Prototypes */
    extern sqlcxt ( void **, unsigned int *,
                       struct sqlexd *, struct sqlcxp * );
    extern sqlcx2t( void **, unsigned int *,
                       struct sqlexd *, struct sqlcxp * );
    extern sqlbuft( void **, char * );
    extern sqlgs2t( void **, char * );
    extern sqlorat( void **, unsigned int *, void * );/* Forms Interface */
    static int IAPSUCC = 0;
    static int IAPFAIL = 1403;
    static int IAPFTL  = 535;
    extern void sqliem( unsigned char *, signed int * );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 short sqlcud0[] =
    {12,4130,1,0,0,
    5,0,0,1,0,0,32,32,0,0,0,0,0,1,0,
    20,0,0,0,0,0,27,44,0,0,4,4,0,1,0,1,97,0,0,1,97,0,0,1,10,0,0,1,10,0,0,
    51,0,0,3,0,0,32,49,0,0,0,0,0,1,0,
    };#include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sqlda.h>
    #include <sqlcpr.h>
    #define     LEN        40typedef char asciiz[LEN]; 
    asciiz     username; 
    asciiz     password;    void sql_error(msg) 
        char *msg;

        char err_msg[512];
        size_t buf_len, msg_len;    /* EXEC SQL WHENEVER SQLERROR CONTINUE; */ 
        printf("\n%s\n", msg);/* Call sqlglm() to get the complete text of the
     * error message.
     */
        buf_len = sizeof (err_msg);
        sqlglm(err_msg, &buf_len, &msg_len);
        printf("%.*s\n", msg_len, err_msg);    /* EXEC SQL ROLLBACK RELEASE; */ {
        struct sqlexd sqlstm;
        sqlstm.sqlvsn = 12;
        sqlstm.arrsiz = 0;
        sqlstm.sqladtp = &sqladt;
        sqlstm.sqltdsp = &sqltds;
        sqlstm.iters = (unsigned int  )1;
        sqlstm.offset = (unsigned int  )5;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
        exit(EXIT_FAILURE);
    } void main()
    {
        strcpy(username, "SCOTT"); 
        strcpy(password, "TIGER");     /* EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--"); */ 
    /* Connect to ORACLE. */
        /* 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  )20;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlstm.sqhstv[0] = (unsigned char  *)username;
        sqlstm.sqhstl[0] = (unsigned long )40;
        sqlstm.sqhsts[0] = (         int  )40;
        sqlstm.sqindv[0] = (         short *)0;
        sqlstm.sqinds[0] = (         int  )0;
        sqlstm.sqharm[0] = (unsigned long )0;
        sqlstm.sqadto[0] = (unsigned short )0;
        sqlstm.sqtdso[0] = (unsigned short )0;
        sqlstm.sqhstv[1] = (unsigned char  *)password;
        sqlstm.sqhstl[1] = (unsigned long )40;
        sqlstm.sqhsts[1] = (         int  )40;
        sqlstm.sqindv[1] = (         short *)0;
        sqlstm.sqinds[1] = (         int  )0;
        sqlstm.sqharm[1] = (unsigned long )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);
        if (sqlca.sqlcode < 0) sql_error("ORACLE error--");
    }    printf("\nConnected to ORACLE as user: %s\n", username); /* Disconnect from ORACLE. */
        /* EXEC SQL ROLLBACK WORK 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  )51;
        sqlstm.cud = sqlcud0;
        sqlstm.sqlest = (unsigned char  *)&sqlca;
        sqlstm.sqlety = (unsigned short)4352;
        sqlstm.occurs = (unsigned int  )0;
        sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
        if (sqlca.sqlcode < 0) sql_error("ORACLE error--");
    }
        exit(EXIT_SUCCESS);
    }
      

  9.   

    struct { unsigned short len; unsigned char arr[40]; }
    然后VARCHAR类型定义是结构体,那么&username就是取该结构体首地址了.你第二种,USERNAME被定义的类型是字符数组,username可以直接当数组首地址使用
      

  10.   


    &username取该结构体首地址,也就是username.len地址,不是username.arr地址。有这么大差别,为什么两个程序功能相同?