`
lc9696lc
  • 浏览: 28811 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

PRO*C中使用动态游标的四种方法

阅读更多

  PRO*C中使用动态游标的四种方法

动态方法1
 

动态方法1的处理过程是先构造一个动态SQL语句然后用EXECUTE IMMEDIATE来执行,EXECUTE IMMEDIATE的功能是分析动态的语句的文本,检查是否有错误,
如果SQL 语句仅执行一次动态方法1的效率很高,动态方法1一定不是SELECT 语句
            1  EXEC SQL EXECUTE IMMEDIATE CREATE TABLE .............;
           
            2 sprintf(host_string,"");
               EXEC SQL EXECUTE IMMEDIATE :host_string ;

动态方法2

方法2与方法1 类似也是能含有SELECT语句,方法2中含义虚拟输入宿主变量,比方法1 多了一步SQL语句的语法分析,
 处理方式分为3步:
                构造一个动态SQL
                用PREPARE分析和命名该SQL
                用EXECUTE来执行它
    用法: sprintf(host_string,"DELETE FROM table_name WHERE no=:v1 AND name=:name");(拼带有输入宿主变量的SQL)
          EXEC SQL PREPARE sql_name FROM :host_string;(分析语法)
          EXEC SQL EXECUTE IMMEDIATE sql_name USING :v1,:name;(传递实际变量)
         
动态方法3

方法就是使用游标,查询并返回多行,如果在方法1和方法2中的SELECT 语句查询返回一行的话,也可以使用SELECT 语句,
方法为 SELECT column1,column2...INTO:variale1,variable2;
方法3是专门解决一次返回多行的,使用方法:
                                      1  拼成一个 SQL sprintf(host_string,"")
                                      2  用EXEC SQL PREPARE name FROM :host_string 来分析其语法
                                      3  用EXEC SQL DECLARE c_name CURSOR FOR : name 来声明游标
                                      4  用EXEC SQL OPEN c_name ;
                                      5  用EXEC SQL FETCH c_name INTO:variable1,:variable2;取出游标中的数据
                                      6  EXEC SQL CLOSE c_name;关闭游标
         
三种动态SQL方法的特点都是先在C语言中拼成所需要的SQL 文本串,然后用EXECUTE IMMEDIATE 来执行

 

下面是我从网上收集的可以和我的对照,ProC前三种动态SQL的完整示例。

 

 

下面是ProC前三种动态SQL的完整示例。

 

(1)动态SQL1: 不能是查询(SELECT)语句,并且没有宿主变量. 
用法:拼一句动态SQL语句,并用EXECUTE IMMEDIATE执行,如:
 
EXEC SQL EXECUTE IMMEDIATE CREATE TABLE test (test_col VARCHAR2(4));
EXEC SQL EXECUTE IMMEDIATE INSERT INTO TABLE test ('AAAA');
EXEC SQL EXECUTE IMMEDIATE DELETE test WHERE test_col='AAAA';

 

(2)动态SQL2: 不能是查询(SELECT)语句,并且输入的宿主变量数目是知道的,
用法:拼一句动态SQL语句,用PREPARE,EXECUTE语句执行.
strcpy(sqlstring, "DELETE FROM test WHERE test_col = :?"); 
EXEC SQL PREPARE sqlproc FROM :sqlstring;
EXEC SQL EXECUTE sqlproc USING :emp_number; 
 
下文示例中大多数是采用动态SQL2.
 
(3)动态SQL3: 用于创建动态查询, 并且要查询的字段以及输入的宿主变量数目是知道的
用法: 拼一句动态SQL语句,用PREPARE分析该语句,并要定义一个CURSOR进行取值
如:要查询的数据在多张表中,select user_name from,可采用动态SQL3来进行查询
strcpy(sql,"select user_name from ");
strcat(sql,"table1");//table2,table3,table4
EXEC SQL PREPARE sqlproc FROM :sql;
EXEC SQL DECLARE cur_user_name CURSOR FOR sqlproc;
EXEC SQL OPEN cur_user_name;
while(1)

EXEC SQL FETCH cur_user_name into :ora_id;
if (sqlca.sqlcode < 0)

/*FETCH CURSOR失败*/ 
printf("fetch cursor fail,sqlcode=%ld,sqlserr=%s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
}
if( sqlca.sqlcode == SQLNOTFOUND)
{
break;
}
}
EXEC SQL CLOSE cur_user_name; 

 

下文示例中Case5也是采用这种方法.

//Proc 示例

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

//变量,过程预声明
int i;
char screen[1];
char cmd[1];

//**********************************************************
//CASE对应与db_selectop的switch
EXEC SQL BEGIN DECLARE SECTION;

VARCHAR oraName[30];    //CASE 1,2,3

VARCHAR oraValue[20];    //CASE 1,2,3,5
int oraCount;          //CASE 1,2,3,4,5
VARCHAR oraSql[30],oraTable[20]; //CASE 4,5

VARCHAR oraField[10];    //CASE 5
VARCHAR oraCountSql[30];   //CASE 5

VARCHAR oraCode[10];    //CASE 6
VARCHAR oraContent[10];    //CASE 6

EXEC SQL END DECLARE SECTION;
//**********************************************************

int db_connect();
int db_selectop();

//void dy_tablecount();
//void dy_tablefield();
void view_tabledata();

void pause();
void sql_error(char *);

//主函数
void main()
{
 EXEC SQL INCLUDE sqlca;
 EXEC ORACLE OPTION (RELEASE_CURSOR = YES);
 EXEC SQL WHENEVER SQLERROR DO sql_error(" <ERROR> ");

 if(db_connect()==0)
 {
  db_selectop();
 }
}


//打开数据连接
int db_connect()
{  

 EXEC SQL BEGIN DECLARE SECTION;
 VARCHAR oraCN[30];
 EXEC SQL END DECLARE SECTION;

 printf("----------------------------------");
 printf("\n [ Examples With Oracle DB  ]\n");
 printf("----------------------------------");
 printf("\n                   Designed by Liwei 2005\n");
 cmd[0]='A';
 while(cmd[0]!='0' && cmd[0]!='1')
 {

  printf("\n Confirm DB Source:");
  printf("\n 1:workflow/workflow@if");
  printf("\n 0:Exit;");
  printf("\n Choose:");

  gets(cmd);
  switch(cmd[0])
  {
   case '1':
    strcpy(oraCN.arr,"workflow/workflow@if");
    oraCN.len = strlen(oraCN.arr);
    oraCN.arr[oraCN.len]='\0';

    //EXEC SQL WHENEVER SQLERROR GOTO cnError;
    EXEC SQL CONNECT :oraCN;
    
    printf("\n [OK Connected!] ");
    return 0;

   
    break;
   case '0':
    break;
   default:
    printf("\n [Error Input!] \n");
    break;
  }
 
 }


 
 exit(0);

//cnError:
// printf("\n [Error Oracle Connected!]");
// return 1; 
}

//选择数据操作
int db_selectop()
{
 char order[1];

 cmd[0]='A';
 //order[0]='A';

 while(cmd[0]!='0')
 {
  printf("\n ");
  printf("\n Select DB Method:");
  printf("\n -------------------------------------------");
  printf("\n 1: GetTableCount      STATIC [CLASS_FLOW]");
  printf("\n 2: GetTableField One  STATIC [CLASS_FLOW]");
  printf("\n 3: GetTableField Muti STATIC [USE_POWER]");
  printf("\n");
  printf("\n 4: GetTableCount      DYNAMIC      ");
  printf("\n 5: GetTableField One  DYNAMIC      ");
  printf("\n");
  printf("\n 6: EditTable USE_DEPT");
  printf("\n -------------------------------------------");
  printf("\n 0: Exit");
  printf("\n\n Enter:");

  gets(cmd);

  switch(cmd[0])
  {
   case '1':
    
    EXEC SQL SELECT NVL(COUNT(*),0) INTO :oraCount FROM CLASS_FLOW;
    
    printf("\n <The Table Count> ");
    printf("%d",oraCount);
    pause();
    break;

   case '2':
    
    EXEC SQL DECLARE curOne CURSOR FOR SELECT DISTINCT FLOW_NAME FROM CLASS_FLOW WHERE FLOW_CLASS='请假';
    EXEC SQL SELECT COUNT(DISTINCT FLOW_NAME) INTO :oraCount FROM CLASS_FLOW WHERE FLOW_CLASS='请假';
    EXEC SQL OPEN curOne;
    
    for(i=1;i<=oraCount;i++)
    {    
     EXEC SQL FETCH curOne INTO :oraName;
     oraName.arr[oraName.len]='\0';
     printf("\n <Field List> ");
     printf("%s",oraName.arr);
    }
    EXEC SQL CLOSE curOne;
    pause();
    break;

   case '3':

    EXEC SQL DECLARE curMuti CURSOR FOR SELECT POWER_ID,POWER_NAME FROM USE_POWER ORDER BY POWER_ID ASC;
    EXEC SQL SELECT COUNT(*) INTO :oraCount FROM USE_POWER;
    EXEC SQL OPEN curMuti;
    
    for(i=1;i<=oraCount;i++)
    {    
     EXEC SQL FETCH curMuti INTO :oraValue,:oraName;
     oraValue.arr[oraValue.len]='\0';
     oraName.arr[oraName.len]='\0';
     printf("\n <Fields List> ");
     printf("%-8s",oraValue.arr);
     printf("%-20s",oraName.arr);
    }

    EXEC SQL CLOSE curMuti;

    pause();
    break;

   case '4':

    //EXEC SQL BEGIN DECLARE SECTION;
    //VARCHAR oraSql[30],oraTable[20];
    //int oraCount;
    //EXEC SQL END DECLARE SECTION;

    printf("\n Custom Table ");
    printf("\n ----------------------- ");
    printf("\n Input Table Name:");
    gets(oraTable.arr);

    oraTable.len=strlen(oraTable.arr);
    oraTable.arr[oraTable.len]='\0';

    strcpy(oraSql.arr,"SELECT COUNT(*) FROM "); 
    strcat(oraSql.arr,oraTable.arr);
    oraSql.len=strlen(oraSql.arr);
    oraSql.arr[oraSql.len]='\0';

    printf("\n <SQL STATE> ");
    printf(oraSql.arr);
    printf("\n ");

    EXEC SQL PREPARE sqlDyCount FROM :oraSql; 
    EXEC SQL DECLARE curDyCount CURSOR FOR sqlDyCount; 
    EXEC SQL OPEN curDyCount;
    EXEC SQL FETCH curDyCount INTO :oraCount;
    EXEC SQL CLOSE curDyCount;

    printf("\n <Table Count> ");
    printf("%d",oraCount);
    //dy_tablecount();
    pause();
    break;

   case '5':

    //EXEC SQL BEGIN DECLARE SECTION;
    //VARCHAR oraSql[30],oraTable[10],oraField[10],oraValue[20];
    //VARCHAR oraCountSql[30];
    //int oraCount;
    //EXEC SQL END DECLARE SECTION;

    //接受屏幕数据
    printf("\n Custom Table And Field ");
    printf("\n ----------------------- ");
    printf("\n Input Table Name:");
    gets(oraTable.arr);
    oraTable.len=strlen(oraTable.arr);
    oraTable.arr[oraTable.len]='\0';
    printf(" Input Field Name:");
    gets(oraField.arr);
    oraField.len=strlen(oraField.arr);
    oraField.arr[oraField.len]='\0';


    //组合SELECT语句
    strcpy(oraSql.arr,"SELECT ");
    strcat(oraSql.arr,oraField.arr);
    strcat(oraSql.arr," FROM ");
    strcat(oraSql.arr,oraTable.arr);
    oraSql.len=strlen(oraSql.arr);
    oraSql.arr[oraSql.len]='\0';
    printf("\n <SQL STATE> ");
    printf(oraSql.arr);
    printf("\n");
    //读取内容
    EXEC SQL PREPARE sqlDy FROM :oraSql;
    EXEC SQL DECLARE curDyField CURSOR FOR sqlDy;
    EXEC SQL OPEN curDyField;


    //组合SELECT COUNT语句
    strcpy(oraCountSql.arr,"SELECT COUNT(*) FROM ");
    strcat(oraCountSql.arr,oraTable.arr);
    oraCountSql.len=strlen(oraCountSql.arr);
    oraCountSql.arr[oraCountSql.len]='\0';
    //读取数
    EXEC SQL PREPARE sqlDyCount FROM :oraCountSql; 
    EXEC SQL DECLARE curDyFieldCount CURSOR FOR sqlDyCount; 
    EXEC SQL OPEN curDyFieldCount;
    EXEC SQL FETCH curDyFieldCount INTO :oraCount;


    for(i=1;i<=oraCount;i++)
    {
    EXEC SQL FETCH curDyField INTO :oraValue;
    oraValue.arr[oraValue.len]='\0';
    printf("\n <Field List> ");
    printf("%s",oraValue.arr);
    }
    EXEC SQL CLOSE curDyFieldCount;
    EXEC SQL CLOSE curDyField;
    //dy_tablefield();
    pause();
    break;

   case '6':

    order[0]='A';
    while(order[0]!='0')
    {
     printf("\n ");
     printf("\n Edit Table ");
     printf("\n -------------");
     printf("\n 1: VIEW");
     printf("\n 2: INSERT");
     printf("\n 3: DELETE");
     printf("\n 4: UPDATE");
     printf("\n -------------");
     printf("\n 0: EXIT");
     printf("\n\n Enter:");
     gets(order);

     switch(order[0])
     {
     case '1':
      view_tabledata();
      pause();
      break;
     case '2':
      //INSERT
      printf("\n INSERT ");
      printf("\n ----------------------- ");
      printf("\n ENTER CODE:");
      gets(oraCode.arr);
      oraCode.len=strlen(oraCode.arr);
      oraCode.arr[oraCode.len]='\0';
      printf(" ENTER CONTENT:");
      gets(oraContent.arr);
      oraContent.len=strlen(oraContent.arr);
      oraContent.arr[oraContent.len]='\0';

      EXEC SQL INSERT INTO USE_DEPT VALUES(:oraCode,:oraContent);
      EXEC SQL COMMIT;
      pause();
      break;
     case '3':
      view_tabledata();
      //DELETE
      printf("\n DELETE ");
      printf("\n ----------------------- ");
      printf("\n ENTER CODE:");
      gets(oraCode.arr);
      oraCode.len=strlen(oraCode.arr);
      oraCode.arr[oraCode.len]='\0';
      EXEC SQL DELETE USE_DEPT WHERE DEPT_ID=:oraCode;
      EXEC SQL COMMIT;
      //strcpy(c_sql, "DELETE FROM EMP WHERE EMPNO = :?");  
      //EXEC SQL PREPARE sql_stmt FROM :c_sql; 
      //EXEC SQL EXECUTE sql_stmt USING :emp_number;  
      pause();
      break;
     case '4':
      view_tabledata();
      //UPDATE
      printf("\n UPDATE ");
      printf("\n ----------------------- ");
      printf("\n ENTER CODE:");
      gets(oraCode.arr);
      oraCode.len=strlen(oraCode.arr);
      oraCode.arr[oraCode.len]='\0';
      printf(" ENTER CONTENT:");
      gets(oraContent.arr);
      oraContent.len=strlen(oraContent.arr);
      oraContent.arr[oraContent.len]='\0';

      EXEC SQL UPDATE USE_DEPT SET DEPT_NAME=:oraContent WHERE DEPT_ID=:oraCode;
      EXEC SQL COMMIT;

      pause();
      break;
     default:
      break;
     }
    }
    cmd[0]='6';
    break; 

   default:
    break;
  }

 
 }
 return 0;

}

void view_tabledata()
{
 //VIEW
 EXEC SQL DECLARE curTable CURSOR FOR SELECT DEPT_ID,DEPT_NAME FROM USE_DEPT ORDER BY DEPT_ID ASC;
 EXEC SQL SELECT COUNT(*) INTO :oraCount FROM USE_DEPT;
 EXEC SQL OPEN curTable;

 printf("\n  ");
 printf("%-8s","CODE");
 printf("%-20s","CONTENT");
 printf("\n--------------------");

 for(i=1;i<=oraCount;i++)
 {    
  EXEC SQL FETCH curTable INTO :oraValue,:oraName;
  oraValue.arr[oraValue.len]='\0';
  oraName.arr[oraName.len]='\0';
  printf("\n ");
  printf("%-8s",oraValue.arr);
  printf("%-20s",oraName.arr);
 }

 printf("\n--------------------");

 EXEC SQL CLOSE curTable;
}
//暂停屏幕
void pause()
{ 
 printf("\n\n--Press Enter To Continue--");
 gets(screen);

}
//显示意外错误
void sql_error(char *msg) 
{ 
 //printf("\n%s %ld %s\n", msg,sqlca.sqlcode,(char *)sqlca.sqlerrm.sqlerrmc); 
 printf("\n%s %s\n", msg,(char *)sqlca.sqlerrm.sqlerrmc); 
 //EXEC SQL ROLLBACK RELEASE; 
 db_selectop(); 
}



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/depositpei/archive/2009/02/09/3870424.aspx

 

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/depositpei/archive/2009/02/09/3870424.aspx

分享到:
评论

相关推荐

    游标在Oracle PRO*C中的使用方法及技巧.pdf

    【Oracle PRO*C游标的使用方法及技巧】 Oracle PRO*C是一种预编译器,它允许开发者在C语言中嵌入PL/SQL代码,从而利用C语言的高效性和PL/SQL对数据库的强大操作能力。在处理大量数据时,游标是必不可少的工具,它...

    Pro*c编程电子图书

    Pro*C,全称为Oracle Precompiling C,是Oracle公司推出的一种混合C语言和SQL的编程工具,它允许开发人员在C程序中直接嵌入SQL语句,以提高数据库应用的性能和效率。这种技术特别适用于需要高效访问Oracle数据库的...

    Oracle Pro*C 编程入门.pdf

    1. Pro*C简介:Pro*C是一种将SQL语句嵌入C程序中的开发工具,它允许开发者在C语言中直接使用SQL语句访问Oracle数据库。它是一种第三代语言嵌入式SQL工具,可以在Oracle数据库管理系统中使用。Pro*C程序可以执行...

    《精通Oracle 10g Pro*C/C++编程》源代码与学习笔记

    Pro*C中使用游标来逐行处理查询结果,而绑定变量则用于在SQL语句中传递参数,提高性能并减少SQL注入的风险。 4. **异常处理**:Oracle提供了一套完整的错误处理机制,Pro*C编程中需要了解如何捕获和处理Oracle的...

    pro*c sample

    Pro*C是Oracle公司开发的一种预编译器,它允许程序员在C语言中嵌入PL/SQL代码,使得C程序可以直接与Oracle数据库交互。通过Pro*C,开发者可以利用C语言的强大功能和效率,同时享受Oracle数据库提供的高级数据库操作...

    Pro*C程序设计ORACLE调用接口

    《Pro*C程序设计ORACLE调用接口》是关于在C语言中使用Oracle数据库的一种高效方法。Pro*C,全称为Pre-Compiler for C,是Oracle公司提供的一个预编译器,它允许开发者直接在C程序中嵌入SQL语句,极大地提高了数据库...

    PRO*C入门实例

    在IT领域,PRO*C是Oracle公司提供的一种预编译器,它允许开发人员使用C语言来编写PL/SQL代码,从而更高效地与Oracle数据库进行交互。这个“PRO*C入门实例”可能是针对初学者的一个教程,通过一个实际的代码示例来...

    linux下c/c++连oracle数据库技术pro*c

    Pro*C是Oracle公司提供的一种预编译器,它允许C或C++程序直接调用PL/SQL代码,极大地简化了数据库操作。本篇文章将详细探讨Linux下使用C/C++和Pro*C连接Oracle数据库的技术细节。 1. **Pro*C介绍**: Pro*C是...

    pro*c程序设计详解

    - **游标和PL/SQL块**:Pro*C支持在C代码中使用游标来处理查询结果,并可以嵌入PL/SQL块来执行复杂的数据库操作。 3. **Pro*C的语法特性**: - **EXEC SQL**:这是Pro*C中用于插入SQL语句的关键字,如`EXEC SQL ...

    Pro*C/C++ 编程

    Pro*C/C++ 是一种集成在C或C++编程语言中的预处理器,它允许程序员直接在源代码中嵌入PL/SQL语句,用于与Oracle数据库进行交互。这种编程方式提供了高效且灵活的数据库访问手段,特别适合于开发与Oracle数据库紧密...

    oracle pro*c入门

    9. **带参动态SQL**:Pro*C允许使用动态SQL来构建和执行在运行时决定的SQL语句,这对于处理参数化查询非常有用。 10. **oci接口**:除了Pro*C,Oracle还提供了Oracle Call Interface (OCI),这是一种更底层的C接口...

    精通PRO*c编程

    PRO*C是Oracle Corporation为C程序员设计的一种工具,它允许在C程序中嵌入SQL语句,使得C语言能够与Oracle数据库无缝集成。 一、PRO*C简介 PRO*C是Oracle数据库的C语言接口,它扩展了C语言,增加了对SQL和PL/SQL的...

    pro*c 实现分页总结

    Pro*C,是Oracle提供的一种预编译器,用于将C语言与PL/SQL结合,使得在C/C++程序中可以直接操作Oracle数据库。本文将深入探讨如何在Pro*C中实现分页查询,主要关注两种常用的方法。 首先,让我们回顾一下基本的分页...

    PRO*C的批量读取

    PRO*C(也称为预编译C)是一种允许在C程序中嵌入SQL语句的技术,它结合了C语言的强大功能与Oracle数据库的高效数据处理能力。本文主要探讨如何使用PRO*C进行高效的大规模数据导出。 #### 二、问题概述 假设有一个...

    pro*c 的 资料

    - **游标**:在 Pro*C 中,游标用于处理 SELECT 语句返回的结果集,可以逐行处理数据,通过声明和使用游标,可以实现更复杂的查询逻辑。 总之,Pro*C 提供了一种高效且灵活的方式,让开发者能够利用 C 语言的强大...

    游标最简单教程

    6. **关闭游标**和**删除游标**:最后分别使用`CLOSE MyCURSOR;`和`DEALLOCATE MyCURSOR;`来关闭和删除游标。 ##### 示例2:更新详细信息日期 ```sql DECLARE varID VARCHAR2(20); DECLARE varDate DATE; CURSOR ...

    使用Pro*C/C++ 开发嵌入式SQL程序

    首先,Pro*C/C++是Oracle提供的一种预编译器,它的主要功能是将C/C++源代码中的嵌入式SQL语句转换为标准的Oracle调用接口(OCI)调用。这样,程序员可以利用C/C++的强大编程能力,同时享受到SQL的便利性,实现对...

    Oracle9iPro*C/C++编程指南源码

    3. **游标处理**:Pro*C/C++支持游标操作,可以用于遍历查询结果集,实现逐行处理数据。 4. **异常处理**:使用Oracle的异常处理机制,开发者可以捕获和处理数据库操作中的错误,确保程序的健壮性。 5. **类型映射...

    Pro*C/C++ Programmer’s Guide, 10g Release 2 (10.2)

    1. **SQL语句的嵌入**:在C/C++源代码中使用特定的标记来标识SQL语句。 - 例如,使用`{ ? }`或`/* ? */`来包裹SQL语句。 2. **变量声明**:声明用于存储查询结果或输入参数的变量。 - 示例:`char emp_name[30];` ...

    QSQL.ZIP_oracle_oracle source_pro*c_qsql

    3. **QSQL的实现**:如果QSQL是一个库,那么压缩包可能包含库的头文件和库文件,以及如何在C程序中使用QSQL的示例代码。如果QSQL是一个工具,那么可能会有如何运行和配置它的说明。 4. **可能的API参考**:如果QSQL...

Global site tag (gtag.js) - Google Analytics