【问题标题】:String returned from oracle stored procedure to Java with '???'从 oracle 存储过程返回到 Java 的字符串带有 '???'
【发布时间】:2012-01-09 12:26:59
【问题描述】:

我的 Java 代码调用 Oracle DB 中的存储过程并返回带有一些字段的对象。 当我从对象中找出属性时 - 我的字符串有问题。字符串变为'???' (3个问号)不应该是这样! (整数返回OK)

我在数据库上测试了我的存储过程 - 它运行良好。

我用调用数据库的小型本地主程序测试了我的 Java 代码 - 它运行良好。 (数据库的连接直接与 DriverManager.getConnection("jdbc:oracle:thin:@......); )

当我在我的大项目中使用我的存储过程通过 weblogic 连接到数据库时出现了问题。

当我使用 WebLogic 时,您知道如何从数据库中获取正确的字符串吗?

Oracle 代码:

  PROCEDURE SearchOrder (InWoArr IN WoTab,
                     OutWoAccStat OUT WoAccStatTab) as
  outRec WoAccStatType;
  wo number(10);
  acc number(10);
  stat varchar2(2);
  begin
  OutWoAccStat := WoAccStatTab();
    for i in InWoArr.FIRST .. InWoArr.LAST loop
    OutWoAccStat.EXTEND;
      begin
       select work_order_number,account_number,' '
    into wo,acc,stat
    from table1
    where work_order_number=InWoArr(i);
    ....
    outRec := WoAccStatType(wo,acc,stat);
    OutWoAccStat(i) := outRec;
  exception
    when no_data_found then
      outRec := WoAccStatType(InWoArr(i),0,' ');
      OutWoAccStat(i) := outRec;
  end;
end loop;
end SearchOrder;

//200 个数组

create or replace type poldev_dba.WoAccStatTab as VARRAY(200) of WoAccStatType

//数组类型

create or replace type poldev_dba.WoAccStatType as object (work_order_number number(10), account_number number(10), wo_status varchar2(2))

//Java代码:

              //Store Procedure Name
          CallableStatement cs = (CallableStatement) con.prepareCall("{ call spp.SearchOrder( ?, ? )}");                                                                                    

          //input:
          cs.setArray(1,woInput);

          //Output:
          cs.registerOutParameter(2,OracleTypes.ARRAY,"WOACCSTATTAB");

          //Run the query...
          cs.execute();

          //Retrieve Array:
          woAccArray = (ARRAY)cs.getArray(2);
          woAccRecs = (Object[])woAccArray.getArray();

          int wo = 0;
          int acc = 0;
          String stat;

          for (int i = 0; i < woAccRecs.length; i++) {
              /* Since we don't know the type of the record, get it into STRUCT !! */
              STRUCT woAccRec = (oracle.sql.STRUCT)woAccRecs[i];
              /* Get the attributes - nothing but the columns of the table */
              Object[] attributes = woAccRec.getAttributes();

              /* attribute 0 - work order */
              wo = Integer.parseInt("" + attributes[0]);

              /* attribute 1 - account number */
              acc = Integer.parseInt("" + attributes[1]);

              /* attribute 2 - status */
              stat = (String) attributes[2]; 
              /*PROBLEM!!!! stat returned value '???'*/

              System.out.println("wo = " + wo + ",acc = " + acc +", status = "+stat);

【问题讨论】:

  • 字符串应该是什么?我怀疑 显示 字符串时存在编码和字体问题。尝试调试您的程序并在从存储过程返回时检查字符串的内容,以了解它是否真的 ???
  • 字符串是“C”或“O”。没有工作。我将其更改为“0”或“”-仍然无效。 (通过连接到数据库的小主程序,它可以正常工作并返回“C”和“O”)
  • 你试过用 NVARCHAR2 代替 VARCHAR2 吗?
  • 谢谢大家!!! SWeko 是对的。在我将变量从 varchar2 更改为 nvarchr2 后开始工作!!!

标签: java stored-procedures jdbc oracle10g weblogic


【解决方案1】:

问题出在其他地方。 Oracle DB 和 DB 驱动程序都不会用??? 替换结果列。在您的产品代码中搜索此字符串以了解使用它的原因。

【讨论】:

  • 我添加了我的 Java 代码。我不认为代码本身存在问题。如果我错了 - 请纠正我。
  • 您的代码看起来正确。尝试不同版本的 Oracle JDBC 驱动程序;也许这是一个错误。如果这不起作用,请将存储过程替换为 Java 代码。我总是尽量避免使用存储过程,因为它们通常会导致比解决的问题更多的问题。使用它们的主要原因是 a) 在通用 API 中隐藏特定于数据库的代码(当您编写支持许多数据库的产品时)或 b) 当您需要 JDBC 不支持的功能时。
  • "我总是尽量避免使用存储过程,因为它们通常会导致比解决的问题更多的问题" - 这是一个糟糕的评论,实际上是不正确的,存储过程非常有用,是排序和限制记录的最佳方法从数据库中返回。仅仅因为您遇到问题并不意味着所有人都应该避免它们。
  • 我在 SELECT 查询中进行排序/限制... :-) 如您所见,评论字段太小,无法进行深入讨论。我的立场仍然是存储过程经常被滥用,因此很危险。
  • 我的产品将包含许多对数据库的调用,也许客户将来会希望在查询中更改某些内容。使用存储过程将使我们能够在不更改代码本身的情况下更改存储过程。
猜你喜欢
  • 2013-06-19
  • 2016-05-07
  • 2021-11-22
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 2011-01-31
相关资源
最近更新 更多