今天项目中需要用到存储过程,使用的是字符串数组作为参数,经过不断尝试,终于搞定了
下面简单的记录下:

1、创建自定义数据类型
--自定义数据类型(可做数组用)

create or replace type jqjk_array AS VARRAY(50) of varchar(50); 

2、创建遍历数组循环的存储过程

CREATE OR REPLACE PROCEDURE testvarray(s_table  in jqjk_array,                                       t_table  in jqjk_array,                                       pk_field in jqjk_array,                                       dd       out varchar) IS  s_tableValue  varchar2(50);  t_tableValue  varchar2(50);  pk_fieldValue varchar2(50);BEGIN  dd := 'success';  for i in 1 .. s_table.count LOOP    BEGIN      s_tableValue  := s_table(i);      t_tableValue  := t_table(i);      pk_fieldValue := pk_field(i);      if s_tableValue is null or t_tableValue is null or         pk_fieldValue is null then        dd := '存在为空的值 ';        exit;      else      --调用另外一个存储过程,传入参数        pro_data_synchronic(s_tableValue, t_tableValue, pk_fieldValue);      end if;            EXCEPTION WHEN dup_val_on_index         THEN dd := 'error ';        exit;      end;

  end LOOP;END testvarray;

这是上一个过程中调用的存储过程,用于同步两张结构一样的表的数据

create or replace procedure pro_data_synchronic (s_table nvarchar2, t_table nvarchar2, pk_field nvarchar2)as    step_one_sql varchar2(2000);   step_two_sql varchar2(2000);   step_three_sql varchar2(2000);   delete_sql varchar2(200);   s_pk_field varchar2(50);   t_pk_field varchar2(50);   s_ts varchar2(50);   t_ts varchar2(50);begin    /**   * 数据同步主要分为三步:   * 第一步:先删除目标表中存在的,但是来源表中不存在的数据(主要处理来源表物理删除的数据)   * delete from jq_bd_bdinfo where pk_bdinfo not in (select pk_bdinfo from bd_bdinfo);   *   * 第二步:删除已同步给目标表,但数据在源表中做过更新的数据   * delete from jq_bd_bdinfo where pk_bdinfo in    *         (select  bd_bdinfo.pk_bdinfo from bd_bdinfo   *                    inner join jq_bd_bdinfo on bd_bdinfo.pk_bdinfo=jq_bd_bdinfo.pk_bdinfo and bd_bdinfo.ts != jq_bd_bdinfo.ts);   *   * 第三步:同步源表中存在但目标表中不存在的数据给目标表   * insert into jq_bd_bdinfo select * from bd_bdinfo where bd_bdinfo.pk_bdinfo not in (select pk_bdinfo from jq_bd_bdinfo);   **/

   s_pk_field := s_table || '.' || pk_field;   s_ts := s_table || '.' ||'ts';   t_pk_field := t_table || '.' || pk_field;   t_ts := t_table || '.' ||'ts';

   delete_sql := 'delete from ' || t_table || ' where '|| pk_field;

   step_one_sql := delete_sql || ' not in (select ' || pk_field || ' from ' || s_table || ')';

   DBMS_OUTPUT.PUT_LINE(step_one_sql);

   step_two_sql := delete_sql || ' in (' || ' select ' || t_pk_field || ' from ' || t_table;   step_two_sql := step_two_sql || ' inner join ' || s_table || ' on ' || s_pk_field || '=' || t_pk_field;   step_two_sql := step_two_sql || ' and ' || s_ts || '!=' || t_ts;   step_two_sql := step_two_sql || ' )';

   DBMS_OUTPUT.PUT_LINE(step_two_sql);

   step_three_sql := 'insert into ' || t_table || ' select * from ' || s_table || ' where ' || s_pk_field;   step_three_sql := step_three_sql || ' not in ( select ' || t_pk_field || ' from ' || t_table || ')';

   DBMS_OUTPUT.PUT_LINE(step_three_sql);

   execute immediate step_one_sql;

   execute immediate step_two_sql;

   execute immediate step_three_sql;

   commit;

end;

3、下面看下java代码中是如何调用的

public void testArrayProceduer() {       String[] t_table = { "jq_CORP",                "jq_BDINFO",                "jq_CURRTYPE",              "jq_PSNDOC",                "jq_DEPTDOC",               "jq_CUBASDOC",              "jq_CASHFLOW",              "jq_JOBBASFIL",             "jq_GLORG",             "jq_GLORGBOOK",             "jq_ACCSUBJ",               "jq_VOUCHER",               "jq_DETAIL",                "jq_FREEVALUE",             "jq_BALANCE",               "jq_VERIFYDETAIL",              "jq_GLBOOK",                "jq_JobMngFil",             "jq_cashflowcase",              "jq_vouchertype",               "jq_user" };        String[] s_table = { "bd_corp", "BD_BDINFO", "BD_CURRTYPE","BD_PSNDOC" ,                 "BD_DEPTDOC", "BD_CUBASDOC", "BD_CASHFLOW",             "BD_JOBBASFIL", "BD_GLORG", "BD_GLORGBOOK", "BD_ACCSUBJ",             "GL_VOUCHER", "GL_DETAIL", "GL_FREEVALUE", "GL_BALANCE",              "GL_VERIFYDETAIL", "BD_GLBOOK", "bd_JobMngFil","GL_CASHFLOWCASE",             "BD_VOUCHERTYPE", "SM_USER" };        String[] pk_field = { "pk_corp", "pk_bdinfo", "pk_currtype","pk_psndoc" ,                "pk_deptdoc", "pk_cubasdoc", "pk_cashflow",             "pk_jobbasfil", "pk_glorg", "pk_glorgbook", "pk_accsubj",             "pk_voucher", "pk_detail", "pk_freevalue", "pk_balance",              "pk_verifydetail", "pk_glbook", "pk_jobmngfil","pk_cashflowcase",             "pk_vouchertype", "cuserid" };        ResultSet rs = null;     ArrayDescriptor arrDesc = null;      CallableStatement proc = null;       try {                     proc = getConn().prepareCall(                    "{ call cs_20120208.testvarray(?,?,?,?) }");            arrDesc = ArrayDescriptor.createDescriptor("JQJK_ARRAY", getConn()); // jqjk_array          /*重要!如果遇到在存储过程中获取不到参数或者获取到的参数值为null时, 请检查有没有加载该类库orai18n.jar(11g之前:nls_charset12.jar)*/                        ARRAY array1 = new ARRAY(arrDesc, getConn(), s_table);           ARRAY array2 = new ARRAY(arrDesc, getConn(), t_table);           ARRAY array3 = new ARRAY(arrDesc, getConn(), pk_field);          proc.setArray(1, array1);         proc.setArray(2, array2);         proc.setArray(3, array3);         proc.registerOutParameter(4, Types.VARCHAR);          proc.execute();

         String ss = (String) proc.getObject(4);          System.out.println(" 返回结果: " + ss);     } catch (SQLException ex2) {          ex2.printStackTrace();        } catch (Exception ex2) {         ex2.printStackTrace();        } finally {           try {             closeConn();              if (rs != null) {                    rs.close();                   if (proc != null) {                      proc.close();                 }             }         } catch (SQLException ex1) {          }     } }

这种情况也可以通过下面两种方式实现:
1、将数组改为一个用逗号连接的字符串,到存储过程中进行拆分;
2、将需要传入的数组放入一个表中,在存储过程中使用游标遍历
如:

CREATE OR REPLACE PROCEDURE optjqr(rs out varchar) IS  s_tableValue  varchar2(50);  t_tableValue  varchar2(50);  pk_fieldValue varchar2(50);  CURSOR  CUR_TEMP is    select s_table, t_table, pk_field from jq_param ORDER BY nm;BEGIN  rs := 'success';  open CUR_TEMP;  LOOP     --把游标的某行值赋值给变量    fetch CUR_TEMP      into s_tableValue, t_tableValue, pk_fieldValue;      --调用存储过程      pro_data_synchronic(s_tableValue, t_tableValue, pk_fieldValue);           --无数据时退出    EXIT WHEN CUR_TEMP%NOTFOUND;  end LOOP;  --关闭游标  if CUR_TEMP%isopen then    close CUR_TEMP;  end if;END optjqr;

以字符串数组为输入参数的存储过程相关推荐

  1. 【C语言】字符串和字符串数组的输入和陷阱

    浅谈:C语言写程序时,因为没有字符串数据类型,所以字符串和字符串数组的输入也是一个难题和陷阱,这里讨论一下几种字符串输入情况. 字符串输入函数: 1.格式输入函数:int scanf("%s ...

  2. Java中字符串数组的输入与输出

    今天刷题遇到一个坑,老是接收不到字符串数组.即用str[i]=sc.nextLine();这样的方式去接收数组的话,打印的时候总是会少一个. import java.util.Scanner;publ ...

  3. C语言 字符串数组 的输入 总结

    小白见解,有问题请批评指正 1.字符串数组的定义 char *str[] = { }; 每个元素都是指针,指向存储空间中的某个字符串 取其中的值的时候直接用str[i]来取 //上面的内容使用注释的话 ...

  4. C++ 传递字符串数组给函数参数

    C++ 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址. 对于传入字符串数组同理,所以如果在函数中对传入的字符串数组进行改变,函数外的字符串数组也会同时改变 举个简单的例子: voi ...

  5. C语言学习笔记09-数组、字符数组、字符串数组、二维数组(单字符输入输出putchar、getchar,字符串输入输出的scanf、gets、puts)

    C语言数组   数组作用:可以用来保存很多记录(可以看成一种大容器).一些简单游戏也基本由数组实现,如游戏地图(二维数组)等等.   一个数组 划分 多个单元(下标区分) -存放-> 多个同类元 ...

  6. 【C语言】字符串(main函数参数)

    文章目录 字符串 字符数组 字符串定义 字符串输入输出scanf&printf 字符串数组 main函数参数 字符串 字符数组 #include <stdio.h>int main ...

  7. 带有无参数的存储过程

    SQL中调用存储过程语句:call procedure_name(); 注:调用时"()"是不可少的,无论是有参数还是无参数. 定义对数据库存储过程的调用时 1.无参数存储过程:{ ...

  8. java 控制台输入字符串_Java控制台输入字符串及字符串比较

    需求描述:茵茵很喜欢研究车牌号码,从车牌号码上可以看出号码注册的早晚,据研究发现,车牌号码是按字典序发放的,现在她收集了很多车牌号码,请你设计程序帮她判断注册较早的号码.车牌号码由5个字母或数字组成. ...

  9. matlab字符串数组里里固定格式的内容,字符串数组和字符数组中的文本

    用字符串数组表示文本 您可以使用 string 数据类型将任何 1×n 字符序列存储为字符串.从 R2017a 开始,您可以用双引号将文本括起来以创建字符串. str = "Hello, w ...

最新文章

  1. mysql分组取日期最大的记录_mysql 分组 group by, 排序 取每条记录中,时间最大
  2. LeetCode 1019. 链表中的下一个更大节点(单调栈)
  3. 一起谈.NET技术,基于Visual Studio 2010 阐述C#4个特性
  4. 【常用模块】OLED显示模块(原理讲解、STM32实例操作)
  5. python求方程的根_python计算方程式根的方法
  6. Spring Boot实现QQ邮件发送,用户注册功能——前后端分离版
  7. 解决微信小程序wx:if使用不了函数,WXS使用方法以及防踩坑
  8. Linux 网桥功能使用
  9. Ubuntu 12.10下用Pidgin(pidgin-lwqq)登录QQ
  10. 五年之后的前端会是什么样?
  11. Linux下测试SSD硬盘读写速率
  12. C# 使用AD(Active Directory)验证内网用户名密码
  13. PowerDesigner生成带中文注释的ER图
  14. 小红书【服饰穿搭】有多火?2022年种草笔记超125万
  15. 2019年测试行业展望
  16. Function和function
  17. pwm整流器及其控制_T型三相三电平整流器的控制实现和仿真
  18. android 查看包名 脚本,Monkeyscript---获取包名主界面名和位置坐标
  19. 成都工业大数据研究院
  20. ARM GUN汇编标准

热门文章

  1. linux makefile 宏定义
  2. editplus 常用快捷键汇总 大小写代码折叠
  3. python socket 简介
  4. 关于SysinternalsSuite全部工具【详解】
  5. 《UNIX环境编程》第十六章--网络IPC:套接字
  6. Android 开发常用代码片段
  7. (七)OpenStack---M版---双节点搭建---Dashboard安装和配置
  8. kafka0.9 java commit_kafka提交offset失败
  9. php用w获取的星期不对,php获取时间是星期几的方法是什么
  10. java after方法_spring AOP的After增强实现方法实例分析