- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试将 oracle 过程调用的输出参数强制转换为一个对象。它不起作用,因为 - 据我了解 - 我需要定义一个 map ,它告诉方法如何转换它。如果 map 是空的或未正确填充,则它默认为 STRUCT 类型的 Objekt - 这在我的情况下是错误的。
我已经构建了一个示例,它应该可以说明问题:
-- Procedure in database
PROCEDURE myprocedure (
inputParam IN VARCHAR2 (4),
outputOne OUT outputOneSQLType
outputTwo OUT outputTwoSQLType);
-- inside of a package
inside a package mypackage
-- first type
create or replace
TYPE outputOneSQLType IS TABLE OF tableOneExample
-- table of type
create or replace
TYPE tableOneExample AS OBJECT (
somethingOne VARCHAR2 (4)
,somethingTwo NUMBER (12)
)
//java from here
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
import oracle.jdbc.oracore.OracleTypeADT;
import oracle.sql.STRUCT;
...
oracle.jdbc.driver.OracleConnection oracleConn = (oracle.jdbc.driver.OracleConnection) con.getMetaData().getConnection();
final OracleCallableStatement storedProc = (OracleCallableStatement)oracleConn.prepareCall("{call mypackage.myprocedure("+
":inputParam, :outputOne, :outputTwo)}");
storedProc.setString("inputParam", "SomeValue");
storedProc.registerOutParameter("outputOne", OracleTypes.STRUCT, "OUTPUTONESQLTYPE");
storedProc.registerOutParameter("outputTwo", OracleTypes.STRUCT, "OUTPUTTWOSQLTYPE");
storedProc.execute();
//So far so good
//now I am lost - I need to define the map to get the object?
//What should be inside the map?
Hashtable newMap = new Hashtable();
newMap.put("outputOneSQLType", ?????.class);
//If the map is empty, it defaults to STRUCT...
final STRUCT myObject = (STRUCT)storedProc.getObject("somethingOne",newMap);
// myObject.getBytes() gives me an object... but I cannot cast it to anything
由于错误的 map ,我不能使用像这样的东西:
final MyClass myObject = (MyClass)storedProc.getObject("somethingOne",newMap);
我应该如何填充 map ?
编辑 1
oracle 数据库中的条目不能更改。我只是被允许使用它们。为此
stmt.registerOutParameter(2, java.sql.Types.ARRAY, "OUTPUTONESQLTYPE");
不起作用。因为一旦我不使用“OracleTypes.STRUCT”就会抛出异常。似乎在 outputOneSQLType 内部有一个类型为“OracleTypeCOLLECTION”的对象
当我尝试
Hashtable newMap = new Hashtable();
newMap.put("outputOneSQLType",OracleTypeCOLLECTION.class);
final OracleTypeCOLLECTION myObject = (OracleTypeCOLLECTION)storedProc.getObject("somethingOne",newMap);
我得到一个异常:InstantiationException: oracle.jdbc.oracore.OracleTypeCOLLECTION
@DazzaL:我将尝试定义一个 SQLDATA 接口(interface)。也许这就是解决方案
解决方案
@DazzaL:你统治!谢谢。
最佳答案
你必须定义一个 sqldata 对象来映射它。
文档:http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraarr.htm#JJDBC28574
例如:
SQL> create or replace TYPE tableOneExample AS OBJECT (
2 somethingOne VARCHAR2 (4)
3 ,somethingTwo NUMBER (12)
4 );
5 /
Type created.
SQL> create or replace TYPE outputOneSQLType IS TABLE OF tableOneExample;
2 /
Type created.
SQL>
SQL> create or replace PROCEDURE myprocedure (
2 inputParam IN VARCHAR2,
3 outputOne OUT outputOneSQLType)
4 as
5 begin
6 outputOne := outputOneSQLType(tableOneExample('a', 1), tableOneExample('b', 2));
7 end;
8 /
Procedure created.
现在我们定义 SQLDATA 接口(interface):
import java.sql.*;
public class TestArr implements SQLData
{
private String sql_type;
public String attrOne;
public int attrTwo;
public TestArr()
{
}
public TestArr (String sql_type, String attrOne, int attrTwo)
{
this.sql_type = sql_type;
this.attrOne = attrOne;
this.attrTwo = attrTwo;
}
// define a get method to return the SQL type of the object
public String getSQLTypeName() throws SQLException
{
return sql_type;
}
// define the required readSQL() method
public void readSQL(SQLInput stream, String typeName)
throws SQLException
{
sql_type = typeName;
attrOne = stream.readString();
attrTwo = stream.readInt();
}
// define the required writeSQL() method
public void writeSQL(SQLOutput stream)
throws SQLException
{
stream.writeString(attrOne);
stream.writeInt(attrTwo);
}
}
确保流写入/读取的输入和顺序与您的 oracle 类型相同,因为任何不一致都会导致内部表示错误。
然后在主类中,您将其映射如下:
CallableStatement stmt = conn.prepareCall("begin myprocedure(?,?); end;");
stmt.setString(1, "foo");
stmt.registerOutParameter(2, java.sql.Types.ARRAY, "OUTPUTONESQLTYPE"); // YOUR ARRAY TYPE (TO MATCH THE API OUTPUT), NOT OBJECT
stmt.execute();
Array arr = stmt.getArray (2);
Map map = conn.getTypeMap();
map.put("TABLEONEEXAMPLE", Class.forName("TestArr")); // YOUR OBJECT TYPE, NOT ARRAY.
Object[] values = (Object[]) arr.getArray();
for (int i=0; i < values.length; i++)
{
TestArr a = (TestArr)values[i];
System.out.println("somethingOne: " + a.attrOne);
System.out.println("somethingTwo: " + a.attrTwo);
}
结果bieng:
M:\Documents\Sample Code\1>javac TestArr.java
M:\Documents\Sample Code\1>javac ArrayTest.java
Note: ArrayTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
M:\Documents\Sample Code\SQLComplexArray>java ArrayTest
Opening Oracle connection...done.
somethingOne: a
somethingTwo: 1
somethingOne: b
somethingTwo: 2
关于java - 如何在oracle中获取一个表作为输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13801183/
简而言之:我想从可变参数模板参数中提取各种选项,但不仅通过标签而且通过那些参数的索引,这些参数是未知的 标签。我喜欢 boost 中的方法(例如 heap 或 lockfree 策略),但想让它与 S
我可以对单元格中的 excel IF 语句提供一些帮助吗? 它在做什么? 对“BaselineAmount”进行了哪些评估? =IF(BaselineAmount, (Variance/Baselin
我正在使用以下方法: public async Task Save(Foo foo,out int param) { ....... MySqlParameter prmparamID
我正在使用 CodeGear RAD Studio IDE。 为了使用命令行参数测试我的应用程序,我多次使用了“运行 -> 参数”菜单中的“参数”字段。 但是每次我给它提供一个新值时,它都无法从“下拉
我已经为信用卡类编写了一些代码,粘贴在下面。我有一个接受上述变量的构造函数,并且正在研究一些方法将这些变量格式化为字符串,以便最终输出将类似于 号码:1234 5678 9012 3456 截止日期:
MySql IN 参数 - 在存储过程中使用时,VarChar IN 参数 val 是否需要单引号? 我已经像平常一样创建了经典 ASP 代码,但我没有更新该列。 我需要引用 VarChar 参数吗?
给出了下面的开始,但似乎不知道如何完成它。本质上,如果我调用 myTest([one, Two, Three], 2); 它应该返回元素 third。必须使用for循环来找到我的解决方案。 funct
将 1113355579999 作为参数传递时,该值在函数内部变为 959050335。 调用(main.c): printf("%d\n", FindCommonDigit(111335557999
这个问题在这里已经有了答案: Is Java "pass-by-reference" or "pass-by-value"? (92 个回答) 关闭9年前。 public class StackOve
我真的很困惑,当像 1 == scanf("%lg", &entry) 交换为 scanf("%lg", &entry) == 1 没有区别。我的实验书上说的是前者,而我觉得后者是可以理解的。 1 =
我正在尝试使用调用 SetupDiGetDeviceRegistryProperty 的函数使用德尔福 7。该调用来自示例函数 SetupEnumAvailableComPorts .它看起来像这样:
我需要在现有项目上实现一些事件的显示。我无法更改数据库结构。 在我的 Controller 中,我(从 ajax 请求)传递了一个时间戳,并且我需要显示之前的 8 个事件。因此,如果时间戳是(转换后)
rails 新手。按照多态关联的教程,我遇到了这个以在create 和destroy 中设置@client。 @client = Client.find(params[:client_id] || p
通过将 VM 参数设置为 -Xmx1024m,我能够通过 Eclipse 运行 Java 程序-Xms256M。现在我想通过 Windows 中的 .bat 文件运行相同的 Java 程序 (jar)
我有一个 Delphi DLL,它在被 Delphi 应用程序调用时工作并导出声明为的方法: Procedure ProduceOutput(request,inputs:widestring; va
浏览完文档和示例后,我还没有弄清楚 schema.yaml 文件中的参数到底用在哪里。 在此处使用 AWS 代码示例:https://github.com/aws-samples/aws-proton
程序参数: procedure get_user_profile ( i_attuid in ras_user.attuid%type, i_data_group in data_g
我有一个字符串作为参数传递给我的存储过程。 dim AgentString as String = " 'test1', 'test2', 'test3' " 我想在 IN 中使用该参数声明。 AND
这个问题已经有答案了: When should I use "this" in a class? (17 个回答) 已关闭 6 年前。 我运行了一些java代码,我看到了一些我不太明白的东西。为什么下
我输入 scroll(0,10,200,10);但是当它运行时,它会传递字符串“xxpos”或“yypos”,我确实在没有撇号的情况下尝试过,但它就是行不通。 scroll = function(xp
我是一名优秀的程序员,十分优秀!