达梦Proc*示例-封装数据到sqlDa结构体中

前言

此Demo是直接将proc查询出来的数据,封装到sqlda中,注意使用dpc_new工具编译时的兼容oracle参数

proc代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>	
//定义列和绑定变量的最大个数
#define MAX_ITEMS 40  	
//定义列名的最大值
#define MAX_VNAME_LEN 30  
#define MAX_INAME_LEN 30   
int alloc_descriptor(int size,int max_vname_len,int max_iname_len);   
void set_bind_v();    
void set_select_v();
void free_da();   
void sql_error(char *msg);   	
EXEC SQL INCLUDE SQLCA;   
EXEC SQL INCLUDE SQLDA;   	
//宿主变量定义:
EXEC SQL BEGIN DECLARE SECTION;   
    char sql_statement[256]= "select * from test_ora";   
    char type_statement[256]="select f1,f2 from test_ora where f1=1";   
    int f1 = 1;
    int i;   
    VARCHAR username[10];
VARCHAR password[10];
VARCHAR servername[20];
EXEC SQL END DECLARE SECTION;   	
SQLDA *bind_p;   
SQLDA *select_p;   	
int main()    
	{   
	    strcpy(username.arr,"SYSDBA");
	    username.len = strlen(username.arr);
	    username.arr[username.len] = '\0';	
	    strcpy(password.arr,"SYSDBA");
	    password.len = strlen(password.arr);
	    password.arr[password.len] = '\0';

        strcpy(servername.arr,"localhost:5236");
	    servername.len = strlen(servername.arr);
	    servername.arr[servername.len] = '\0';
		
	    EXEC SQL CONNECT :username identified by :password using :servername;
	    printf("\n [OK Connected!] \n\n");   	
	    EXEC SQL WHENEVER SQLERROR DO sql_error("<ERROR>");

        //给sqlda类型 分配数据
	    alloc_descriptor(MAX_ITEMS,MAX_VNAME_LEN,MAX_INAME_LEN);   

        //建表语句
        EXEC SQL CREATE TABLE TEST_ORA(f1 INT, f2 INT);
        EXEC SQL INSERT INTO TEST_ORA VALUES(1,2);
        EXEC SQL INSERT INTO TEST_ORA VALUES(1,4);
		EXEC SQL commit;
        //prepare语句
	    EXEC SQL PREPARE S from :type_statement;   
	    EXEC SQL DECLARE C1 CURSOR FOR S;    
	    set_bind_v();   
	    EXEC SQL OPEN C1 USING DESCRIPTOR bind_p;   
	    EXEC SQL DESCRIBE SELECT LIST for S INTO select_p;

        set_select_v();
	    printf("f1\t\tf2\n");   
	    printf("----------------------------------------------------------\n");   
	    for(;;)   
	    {    EXEC SQL WHENEVER NOT FOUND DO break;   
	
	         EXEC SQL FETCH C1 USING DESCRIPTOR select_p;   
	         for(i = 0;i<select_p->F;i++){   
	            printf("%s ",select_p->V[i]);   
	        }   
	         printf("\n");   
	    }   
	    free_da();   
	    EXEC SQL CLOSE C1;   
	    printf("\n-----------------------------------------------------\n");   
	    alloc_descriptor(MAX_ITEMS,MAX_VNAME_LEN,MAX_INAME_LEN);   
	    EXEC SQL PREPARE S from :sql_statement;   
	    EXEC SQL DECLARE C CURSOR FOR S;    
	    set_bind_v();   
	    EXEC SQL OPEN C USING DESCRIPTOR bind_p;   
	    EXEC SQL DESCRIBE SELECT LIST for S INTO select_p;  
		set_select_v(); 
	    for(;;)   
	    {    EXEC SQL WHENEVER NOT FOUND DO break;          
	         EXEC SQL FETCH C USING DESCRIPTOR select_p;   
	         for(i = 0;i<select_p->F;i++)   
	            printf("%s ",select_p->V[i]);   
	         printf("\n");   
	    }   
	    free_da();   
	    EXEC SQL CLOSE C;          
		EXEC SQL DROP TABLE TEST_ORA;
	    EXEC SQL COMMIT WORK RELEASE;   
	    exit(0);   
	}   	
//分配描述符空间:
int alloc_descriptor(int size,int max_vname_len,int max_iname_len)   
	{   
	    int i;
if((bind_p=SQLSQLDAAlloc(0,size,max_vname_len,max_iname_len))==(SQLDA*)0)   
	    {   
	        printf("can't allocate memory for bind_p.");   
	        return -1;   
	    }   
if((select_p=SQLSQLDAAlloc(0,size,max_vname_len,max_iname_len))==(SQLDA*)0)   
	    {   
	        printf("can't allocate memory for select_p.");   
	        return -1;   
	    }   
	    return 0;   
   }   
	//绑定变量的设置:
	void set_bind_v()   
	{   
	    int i;   
	    EXEC SQL WHENEVER SQLERROR DO sql_error("<ERROR>");   
	    bind_p ->N = MAX_ITEMS;   
	    EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_p;   
	    if(bind_p->F<0)   
	    {   
	        printf("Too Many bind varibles");   
	        return;   
	    }   
	    bind_p->N = bind_p->F;   
	    for(i=0;i<bind_p->N;i++)   
	    {   	
	        bind_p->T[i] = 1;   
	    }   
	}

//选择列处理
	void set_select_v()   
	{   
		    int i,null_ok,precision,scale;   
	     EXEC SQL DESCRIBE SELECT LIST for S INTO select_p;   
	     if(select_p->F<0)   
	    {   
	        printf("Too Many column varibles");   
	        return;   
	    }   
	    select_p->N = select_p->F;   
	    //对格式作处理
	    for(i = 0;i<select_p->N;i++)   
	    {   
	        sqlnul(&(select_p->T[i]), &(select_p->T[i]), &null_ok);//检查类型是否为空
	        switch (select_p->T[i])   
	        {   
	           case 1://VARCHAR2   
	                break;   
	           case 2://NUMBER   
	                sqlprc(&(select_p->L[i]), &precision, &scale);   
	                if (precision == 0)   
	                  precision = 40;   
	                select_p->L[i] = precision + 2;   
	                break;   
	           case 8://LONG   
	                 select_p->L[i] = 240;   
	                 break;   
	           case 11://ROWID   
	                 select_p->L[i] = 18;   
	                 break;   
	           case 12://DATE   
	                 select_p->L[i] = 9;   
	                 break;   
	           case 23://RAW   
	                 break;   
	           case 24://LONGRAW   
	                 select_p->L[i] = 240;   
                 break;   
        }   
	        select_p->V[i] = (char *)realloc(select_p->V[i], select_p->L[i]+1);   
	        select_p->V[i][select_p->L[i]] ='\0';//加上终止符
	        select_p->T[i] = 1;//把所有类型转换为字符型
	     }   
	}    
	//释放内存SQLDA的函数:
	void free_da()   
	{    
	    SQLSQLDAFree(0,bind_p);   
	    SQLSQLDAFree(0,select_p);   
  }   
//错误处理
	void sql_error(char *msg)   
	{   
	    printf("\n%s %s\n", msg,(char *)sqlca.sqlerrm.sqlerrmc);   
	    EXEC SQL ROLLBACK RELEASE;   
	    exit(0);   
	}  

编译参数


export LD_LIBRARY_PATH=/opt/dmdbms/bin
./dpc_new FILE=test_ora_20231024.pc MODE=ORACLE TYPE=C TYPE_MODE=ORACLE UNSAFE_NULL=Y 
gcc  -g -o  test_ora_20231024  test_ora_20231024.c -I"/opt/dmdbms/include"  -L"/opt/dmdbms/bin"   -ldmdpc

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值