云数据库 GaussDB-执行SQL语句:创建和调用存储过程(入参为复合数据类型)

时间:2025-02-12 15:05:56

创建和调用存储过程(入参为复合数据类型)

以下用例展示A兼容模式下,入参为复合数据类型的存储过程创建和调用情况。前置条件是数据库建连完成、连接对象为conn。

创建存储过程test_proc如下:
 1 2 3 4 5 6 7 8 910111213141516171819202122
// 在数据库创建复合数据类型。CREATE TYPE compfoo AS (f1 int, f3 text);// 在数据库中创建table类型create type compfoo_table is table of compfoo;// 在数据库中创建如下存储过程,它带有out参数create or replace procedure test_proc(    psv_in in compfoo,    table_in in compfoo_table,    psv_out out compfoo,    table_out out compfoo_table)asbegin    psv_out := psv_in;    table_out:=compfoo_table();    table_out.extend(table_in.count);    for i in 1..table_in.count loop         table_out(i):=table_in(i);    end loop;end;/

调用存储过程test_proc如下:

  1. 设置参数behavior_compat_options='proc_outparam_override'后,调用Connection的prepareCall方法创建调用语句对象cs。

    123
    Statement statement = conn.createStatement();statement.execute("set behavior_compat_options='proc_outparam_override'");CallableStatement cs = conn.prepareCall("{ CALL TEST_PROC(?,?,?,?) }");

  2. 调用CallableStatement的set方法设置参数。

    12345678
    PGobject pGobject = new PGobject();pGobject.setType("public.compfoo"); // 设置复合类型名,格式为“schema.typename”。pGobject.setValue("(1,demo)"); // 绑定复合类型值,格式为“(value1,value2)”。cs.setObject(1, pGobject);pGobject = new PGobject();pGobject.setType("public.compfoo_table"); // 设置Table类型名,格式为"schema.typename"。pGobject.setValue("{\"(10,demo10)\",\"(11,demo111)\"}"); //绑定Table类型值,格式为"{\"(value1,value2)\",\"(value1,value2)\",...}"。cs.setObject(2, pGobject);

  3. 调用CallableStatement的registerOutParameter方法注册输出参数。

    1234
    // 注册out类型的参数,类型为复合类型,格式为“schema.typename”。cs.registerOutParameter(3, Types.STRUCT, "public.compfoo");   // 注册out类型的参数,类型为Table类型,格式为“schema.typename”。cs.registerOutParameter(4, Types.ARRAY, "public.compfoo_table");

  4. 调用CallableStatement的execute方法执行SQL语句。

    1
    cs.execute();

  5. 调用CallableStatement的getObject方法获取输出参数。

     1 2 3 4 5 6 7 8 9101112
    // 返回结构是自定义类型。PGobject result = (PGobject)cs.getObject(3);  // 获取out参数 result.getValue(); // 获取复合类型字符串形式值。result.getArrayValue(); //获取复合类型数组形式值,以复合数据类型字段顺序排序。result.getStruct(); //获取复合类型子类型名,按创建顺序排序。result.getAttributes(); //返回自定义类型每列组成类型的对象,对于array类型和table类型返回的是PgArray,对于自定义类型,封装的是PGobject,对于其他类型数据存储方式为字符串类型。// 返回结果是Table类型。PgArray pgArray = (PgArray) cs.getObject(4);ResultSet rs = pgArray.getResultSet();while (rs.next()) {  rs.getObject(2);// table类型每行的数据构建成的对象。}

    如果出参的table类型组成为自定义类型,例如create type compfoo_table is table of compfoo,此时接收到的返回对象为PgArray,在通过rs.getObject(2)遍历获取到的组成对象也为PgArray,此时无法获取到组成它的compfoo类型对应的每列数据,需要通过getPGobject()获取到PgObject再操作获取。

  6. 调用CallableStatement的close方法关闭调用语句对象cs。

    1
    cs.close();

  • A兼容模式开启参数后,调用存储过程必须使用{call proc_name(?,?,?)}形式调用,调用函数必须使用{? = call func_name(?,?)}形式调用(等号左侧的“?”为函数返回值的占位符,用于注册函数返回值)。
  • 参数behavior_compat_options='proc_outparam_override'变更后,业务需要重新建立连接,否则无法正确调用存储过程和函数。
  • 函数和存储过程中包含复合类型时,参数的绑定与注册需要使用schema.typename形式。
support.huaweicloud.com/centralized-devg-v8-gaussdb/gaussdb-42-0072.html