Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2896285
  • 博文数量: 599
  • 博客积分: 16398
  • 博客等级: 上将
  • 技术积分: 6875
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-30 12:04
个人简介

WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606

文章分类

全部博文(599)

文章存档

2014年(12)

2013年(56)

2012年(199)

2011年(105)

2010年(128)

2009年(99)

分类: Oracle

2012-08-20 14:23:47

ITPUB里有个网友问到C如何调用返回数组的存储过程,简单做了个例子:
 
一、Pro*C调用返回数组的存储过程
 

点击(此处)折叠或打开

  1. SQL> create or replace procedure getidlist(p_id out dbms_sql.number_table,p_num out number)
  2.   2 is
  3.   3 begin
  4.   4 select level bulk collect into p_id from dual connect by level<=10;
  5.   5 p_num:=p_id.count;
  6.   6 end;
  7.   7 /

  8. Procedure created.


  9. SQL> declare
  10.   2 num_table dbms_sql.number_table;
  11.   3 cnt int;
  12.   4 i int;
  13.   5 begin
  14.   6 getidlist(num_table,cnt);
  15.   7 for i in 1..cnt loop
  16.   8 dbms_output.put_line(num_table(i));
  17.   9 end loop;
  18.  10 end;
  19.  11 /
  20. 1
  21. 2
  22. 3
  23. 4
  24. 5
  25. 6
  26. 7
  27. 8
  28. 9
  29. 10

  30. PL/SQL procedure successfully completed.

  31. SQL>

首先创建了一个返回数组的存储过程,第二个参数表示返回数组的元素个数。

主要的C代码如下:
 

点击(此处)折叠或打开

  1. [oracle@db2server ~]$ vi arraytest.pc

  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <stdlib.h>
  5. exec sql include sqlca;



  6. void sqlerror()
  7.   {
  8.     exec sql whenever sqlerror continue;
  9.     printf("\n% .70s \n", sqlca.sqlerrm.sqlerrmc);
  10.     exec sql rollback work release;
  11.     exit(1);
  12.   }



  13. int main(int argc,char *argv)
  14. {

  15.   exec sql begin declare section;
  16.     int num[100],i,arraysize;
  17.     char * connstr="htyansp/htyansp";
  18.   exec sql end declare section;


  19.   exec sql whenever sqlerror do sqlerror();
  20.   exec sql connect :connstr;
  21.   exec sql execute
  22.      begin
  23.       getidlist(:num,:arraysize);
  24.      end;
  25.   end-exec;
  26.   for(i=0;i<arraysize;i++)
  27.   {
  28.     printf("%d\n",num[i]);
  29.   }
  30.   exec sql commit work release;
  31.   exit(0);
  32. }
  33. "arraytest.pc" 41L, 713C written

编译为可执行文件,执行结果如下:
 

点击(此处)折叠或打开

  1. [oracle@db2server ~]$
  2. [oracle@db2server ~]$ proc parse=none arraytest.pc userid=htyansp/htyansp SQLCHECK=SEMANTICS

  3. Pro*C/C++: Release 11.2.0.1.0 - Production on Sun Aug 19 00:50:44 2012

  4. Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

  5. System default option values taken from: /u01/app/oracle/product/db11gr2/precomp/admin/pcscfg.cfg

  6. [oracle@db2server ~]$ gcc arraytest.c -o arraytest $ORACLE_HOME/lib/libclntsh.so
  7. [oracle@db2server ~]$ ./arraytest
  8. 1
  9. 2
  10. 3
  11. 4
  12. 5
  13. 6
  14. 7
  15. 8
  16. 9
  17. 10

例子中用到了嵌入式PL/SQL块,如果把 PL/SQL块
exec sql execute
     begin
      getidlist(:num,:arraysize);
     end;
  end-exec;
 
改为下面的形式,编译倒是可以能过去,在执行的时候却报错:
 
 exec sql call getidlist(:num,:arraysize);
 

点击(此处)折叠或打开

  1. [oracle@db2server ~]$ proc parse=none arraytest.pc userid=htyansp/htyansp SQLCHECK=SEMANTICS

  2. Pro*C/C++: Release 11.2.0.1.0 - Production on Sun Aug 19 01:02:32 2012

  3. Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

  4. System default option values taken from: /u01/app/oracle/product/db11gr2/precomp/admin/pcscfg.cfg

  5. Warning at line 30, column 12, file arraytest.pc:
  6.   exec sql call getidlist(:num,:arraysize);
  7. ...........1
  8. PCC-W-02344, Host variable array size mismatch. Using minimum: 1
  9. [oracle@db2server ~]$ gcc arraytest.c -o arraytest $ORACLE_HOME/lib/libclntsh.so
  10. [oracle@db2server ~]$ ./arraytest

  11. ORA-06553: PLS-306: ?? 'GETIDLIST' ??????????

二、Pro*C向存储过程传递数组
 

点击(此处)折叠或打开

  1. SQL> desc t;
  2.  名称 是否为空? 类型
  3.  ----------------------------------------- -------- ----------------------------

  4.  ID NUMBER(38)
  5.  NAME
  6.                                            VARCHAR2(30)
  7. SQL> select * from t;

  8. 未选定行

  9. SQL>


  10. [oracle@db2server ~]$ vi htyansp.pc


  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <stdlib.h>
  14. exec sql include sqlca;
  15. main()
  16. {
  17.   exec sql begin declare section;
  18.      char * connstr="htyansp/htyansp";
  19.      char v_object_name[10][10]={"A","B","C","D","E","F","G","H","I","G"};
  20.      int v_num[10]={0,1,2,3,4,5,6,7,8,9};
  21.   exec sql end declare section;
  22.   exec sql connect :connstr;
  23.   exec sql execute
  24.     declare
  25.       type num_table is table of int index by binary_integer;
  26.       type name_table is table of char(20) index by binary_integer;
  27.       procedure insert_data(p_num num_table,p_name name_table)
  28.       as
  29.       begin
  30.         forall i in p_num.first..p_num.last
  31.           insert into t values(p_num(i),trim(p_name(i)));
  32.         commit;
  33.       end;
  34.     begin
  35.        insert_data(:v_num,:v_object_name);
  36.     end;
  37.   end-exec;
  38.  exec sql commit work release;
  39. }
  40. ~
  41. ~
  42. ~
  43. ~
  44. ~
  45. ~
  46. ~
  47. ~
  48. ~
  49. ~
  50. "htyansp.pc" [New] 30L, 829C written

编译为可执行文件

点击(此处)折叠或打开

  1. [oracle@db2server ~]$ proc parse=none htyansp.pc userid=htyansp/htyansp SQLCHECK=SEMANTICS

  2. Pro*C/C++: Release 11.2.0.1.0 - Production on Sun Aug 19 01:12:09 2012

  3. Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

  4. System default option values taken from: /u01/app/oracle/product/db11gr2/precomp/admin/pcscfg.cfg

  5. [oracle@db2server ~]$ gcc htyansp.c -o htyansp $ORACLE_HOME/lib/libclntsh.so
  6. [oracle@db2server ~]$ ./htyansp
  7. [oracle@db2server ~]$
执行结果如下:
 

点击(此处)折叠或打开

  1. SQL> select * from t;

  2.         ID NAME
  3. ---------- --------------------

  4.          0 A
  5.          1 B
  6.          2 C
  7.          3 D
  8.          4 E
  9.          5 F
  10.          6 G
  11.          7 H
  12.          8 I
  13.          9 G

  14. 10 rows selected.


阅读(2896) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~