`
z_kanhai
  • 浏览: 51884 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

以字符串数组为输入参数的存储过程

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

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;
分享到:
评论

相关推荐

    输入10个字符串到一个字符串数组

    ` 声明了一个长度为 10 的字符串数组。 - **数组初始化**:`str[i] = scanner.next();` 从用户处接收输入并将其存储在数组中。 #### 3.2 遍历数组 - **for 循环**:使用 for 循环遍历数组。例如,`for (int i = 0; ...

    matlab中的字符串数组与函数调用

    Matlab 中的字符串数组是一种特殊的数组,它可以用来存储和操作字符串数据。字符串数组可以使用 cell 数组或字符数组来表示,下面我们将详细介绍 Matlab 中的字符串数组和函数调用。 一、字符串数组的定义 在 ...

    C#字符串数组转换为整形数组的方法

    在C#编程语言中,有时我们需要将存储数值的字符串数组转换为整型数组,以便进行数值计算或与其他数据结构交互。这个过程涉及到数组的遍历和类型转换。本文将详细探讨如何实现这一转换,并提供一个实用的方法供参考。...

    Swift-model(字符串数组模型)

    在实际开发中,这种字符串数组模型可以应用于各种场景,比如显示列表数据、存储用户输入或者作为API的输入输出参数。理解并熟练掌握如何构建和操作这样的模型是Swift开发者的基本技能之一,它能够帮助你更好地组织和...

    合并一维字符串数组并去重 C#

    假设我们有一个函数`MergeAndRemoveDuplicates`接受两个字符串数组作为参数,那么实现如下: ```csharp public static string[] MergeAndRemoveDuplicates(string[] array1, string[] array2) { var merged = ...

    字符串去重

    1. **定义输入参数**:接收一个字符串数组作为输入。 2. **创建HashSet**:使用`HashSet`来存储不重复的字符串。 3. **添加元素到HashSet**:遍历输入的字符串数组,并将其所有元素添加到`HashSet`中。由于`HashSet`...

    字符串与字节数组之间的转换

    2. **逐字节转换**:遍历输入数组中的每一个字节,将其转换为16进制字符串。如果转换后的字符串长度不足2位,则在其前面补零。 3. **拼接字符串**:将转换后的16进制字符串拼接到结果字符串中。 #### 三、注意事项 ...

    在SQL存储过程中进行参数数组Array Parameter的处理函数

    在SQL Server中,存储过程是预编译的SQL语句集合,它们允许开发人员封装复杂的数据库操作,并且可以接受输入参数来实现灵活的数据处理。在某些情况下,我们需要一次性处理多个值,而不是单个参数,这就是参数数组...

    ArrayToString_数组转换为字符串_

    LabVIEW支持多种类型的数组,包括数值数组、布尔数组、字符串数组等。对于数值数组,可以包含整型、浮点型或其他数值类型的数据;而对于字符串数组,每个元素都是一个字符串。 在LabVIEW中,转换数组为字符串通常...

    OJ_将数组中的字符串按指定长度重新分割

    首先,定义一个方法接收字符串数组和目标长度作为参数,然后遍历数组,对每个字符串进行分割,最后返回新的字符串数组。在这个过程中,我们需要处理可能出现的特殊情况,如字符串长度小于目标长度、数组为空等情况。

    计算机程序设计(C++):C++之字符数组和字符串.doc

    需要注意的是,printf和scanf函数处理字符串数组的特点是直接使用数组名作为参数。例如: printf("%s\n",ary1); 这种直接使用数组名的用法,使得程序更加简洁和高效。 字符数组和字符串是C++中两个非常重要的概念...

    C语言第讲指针与字符串字符数组PPT课件.pptx

    字符串则是以字符数组的形式存在,其有效字符由结束符`\0`来决定,即当遇到`\0`时,表示字符串的结束。因此,字符数组名和字符串的值都是地址,即字符串的首地址。 访问字符串有两种主要方式: 1. **直接引用字符...

    四种方法对字符串排序

    排序过程中利用了`strcmp`函数来比较字符串的大小,并通过一个临时数组`temp`来交换两个字符串的位置。 **示例代码片段**: ```cpp void fun(char s[][5], int m) { int p, q, r; char temp[5]; for (p = 0; p ;...

    PHP多维数组转字符串函数

    有时候,我们可能需要将多维数组转换为字符串形式,以便于存储、传输或者进行其他操作。本文将详细介绍一个来自PLFrame PHP框架中的实用函数——`array_toString()`,该函数可以有效地将多维数组转换为字符串。 ###...

    C语言34:用指针数组作为函数的参数显示多个字符串.rar

    本主题将深入探讨如何使用指针数组作为函数参数来显示多个字符串。指针数组结合了指针和数组的特性,使我们能够灵活地处理一系列相关的数据。 首先,我们要理解指针的基本概念。指针是一个变量,它存储的是另一个...

    Python实现查找字符串数组最长公共前缀示例

    在Python编程中,查找字符串数组的最长公共前缀是一项常见的任务,特别是在处理文本数据或进行字符串分析时。这个过程涉及到字符串的遍历、比较以及判断,以找到所有字符串共享的最长的起始部分。以下是一个详细的...

    查找字符串中最小字符串-C语言代码

    接下来,我们要定义一个函数,这个函数接收一个字符串数组作为参数,然后返回这个数组中最短的字符串。我们可以创建一个变量来保存当前找到的最短字符串的长度,初始化为一个非常大的值,这样任何字符串的长度都比它...

    C_Array_And_String.rar_string array

    3. 命令行参数:命令行参数通常以字符串数组的形式传递给main()函数。 4. 词频统计:在文本分析中,可以使用字符串数组存储不同单词,并用整数数组记录对应出现次数。 总之,理解并熟练掌握C语言中的数组和字符串...

    Mysql通过存储过程分割字符串为数组

    - `sp_print_result` 存储过程,接受一个字符串和分隔符,利用前两个函数生成临时表,存储分割后的子字符串,并打印结果。 5. **存储过程与函数的区别**: - **存储过程** 是一组可执行的SQL语句,可以有输入/...

    C#实现String字符串转化为SQL语句中的In后接的参数详解

    // 遍历分割后的字符串数组,构建SQL参数列表 for (int i = 0; i ; i++) { // 去除重复的输入值 if (!bb1.Contains(bb[i])) { // 在每个参数前后添加单引号,并用逗号分隔 bb1 += "'" + bb[i] + "',"; } }...

Global site tag (gtag.js) - Google Analytics