标签: callable-statement

存储过程作为查询:CallableStatement与PreparedStatement

PostgreSQL文档建议使用a CallableStatement来调用存储过程.

对于返回行集的存储过程,使用时有什么区别CallableStatement:

String callString = "{ call rankFoos(?, ?) }";
CallableStatement callableStatement = con.prepareCall(callString);
callableStatement.setString(1, fooCategory);
callableStatement.setInt(2, minimumRank);
ResultSet results = statement.executeQuery();
Run Code Online (Sandbox Code Playgroud)

并使用常规PreparedStatement:

String queryString = "SELECT FooUID, Rank FROM rankFoos(?, ?);";
PreparedStatement preparedStatement = connection.prepareStatement(queryString);
preparedStatement.setString(1, fooCategory);
preparedStatement.setInt(2, minimumRank);
ResultSet results = statement.executeQuery();
Run Code Online (Sandbox Code Playgroud)

据我所知,CallableStatement提供了一种与语言无关的调用存储过程的方法.这对我来说无关紧要,因为我知道我正在使用PostgreSQL.据我所看到的,使用的明显优势PreparedStatement是更通用的查询,处理存储过程作为一个表,关于这一点我可以使用WHERE,JOIN,ORDER BY,等.

我缺少的方法之间是否存在方面或差异?如果存储过程用作查询,建议使用?

postgresql stored-procedures jdbc prepared-statement callable-statement

13
推荐指数
2
解决办法
1万
查看次数

CallableStatement的性能下降

我在Oracle 11g中有一个存储过程,我使用Oracle瘦数据库驱动程序和CallableStatement从Java程序调用.在同一连接上循环调用此存储过程数千次.

callableStatement.execute()在<200毫秒的第10-20电话呼叫的回报,但是,性能开始随着时间的推移.200次通话后,callableStatement.execute()现在需要600ms,并继续降级.

如果我定期关闭连接,执行时间将恢复到正常的<200ms范围.显然,JDBC连接中的某些内容被错误地缓存,尽管文档声明CallableStatements未被缓存.

在C程序中使用Oracle OCI驱动程序运行相同的存储过程不会导致性能下降,并且会在<200ms内连续返回.

有没有人注意到这种行为或对Java的解决方法有任何想法?

编辑:这是多次运行的代码部分; 连接是共享的,每次循环都会创建CallableStatement.如果CallableStatement被缓存,则没有任何改进.

   oracle_conn_time = System.currentTimeMillis();
   OracleConnection oracle_conn = (OracleConnection) conn.getMetaData().getConnection();
   oracle_conn.setStatementCacheSize(1);
   oracle_conn_time = System.currentTimeMillis() - oracle_conn_time;

   list_time = System.currentTimeMillis();
   var_args= oracle_conn.createARRAY("ARG_LIST", args.toArray());
   list_time = System.currentTimeMillis() - list_time;

   sql       = "{? = call perform_work(?,?,?,?)}";

prepare_time = System.currentTimeMillis();
ocs = (OracleCallableStatement) oracle_conn.prepareCall(sql);
prepare_time = System.currentTimeMillis() - prepare_time;

bind_time = System.currentTimeMillis();
    ocs.registerOutParameter(1, OracleTypes.ARRAY, "RESPONSEOBJ");

    ocs.setInt(  2, 77);
    ocs.setInt(  3, 123456);
    ocs.setArray(4, var_args);
    ocs.setInt(  5, 123456789);
    bind_time = System.currentTimeMillis() - bind_time;

//execute_time is …
Run Code Online (Sandbox Code Playgroud)

java oracle stored-procedures jdbc callable-statement

5
推荐指数
1
解决办法
834
查看次数

JDBC对存储过程的调用返回null

我在Oracle数据库上存储过程时遇到了一些问题.

我只想调用一个过程(它有50个IN参数和2个IN OUT参数)并获得这2个OUT参数.

我正在尝试执行()相关的CallableStatement,但它返回一个NullPointerException

java.lang.NullPointerException
at oracle.jdbc.driver.T4C8Oall.getNumRows(T4C8Oall.java:977)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1363)
...
Run Code Online (Sandbox Code Playgroud)

这是代码(我正在使用Hibernate):

    Session session = (Session) HibernateUtil.currentSession();

    final Transaction transaction = session.beginTransaction();

    try {
        session.doWork(new Work() {

            public void execute(Connection connection) throws SQLException {
                try {
                    CallableStatement call = connection.prepareCall("{?,? = call geneva_admin.bksgnvcrmps.createorreturnproduct1nc(" +
                            "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +
                            "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +
                            "?,?,?,?,?,?,?,?,?,?,?,?)}");

                    int i = 1;

                    call.registerOutParameter(i++, Types.INTEGER);
                    call.registerOutParameter(i++, Types.VARCHAR);


                    call.setString(i++, typeofproduct);
                    call.setString(i++, shiptositenumber);
                    call.setString(i++, billtositenumber);
                    call.setString(i++, ordernumber);
                    call.setInt(i++, orderid);
                    ...
                    call.setInt(i++, errcode);
                    call.setString(i++, errmsg);

                    call.execute();

                    System.out.println("err_code: " + call.getString(1));
                    System.out.println("err_msg: " + call.getString(2)); …
Run Code Online (Sandbox Code Playgroud)

stored-procedures jdbc ora-00911 callable-statement

4
推荐指数
1
解决办法
4267
查看次数

在仅设置某些参数时,如何在JDBC中调用存储过程

如果只想设置一些参数,使用JDBC调用存储过程的最佳方法是什么?

如果我只是使用SQL,我可以在SQL中按名称设置参数,以调用sproc.例如,如果我有一个包含9个参数的存储过程,并且我想设置参数1,2和9,其余的保留其默认值,我可以运行此SQL:

exec my_stored_procedure
    @parameter_1       = "ONE",
    @parameter_2       = "TWO",
    @parameter_9       = "NINE"
Run Code Online (Sandbox Code Playgroud)

使用JDBC(特别是jConnect 6.0),似乎在使用CallableStatement时,您必须通过整数索引而不是其名称来设置参数.如果我尝试为上面的存储过程创建一个CallableStatement,使用9个参数,并且只设置参数1,2和9,如下所示:

myStoredProcedureCall = 
  sybConn.prepareCall("{call my_stored_procedure (?, ?, ?, ?, ?, ? , ?, ?, ?)}");
myStoredProcedureCall.setString(1, "ONE");
myStoredProcedureCall.setString(2, "TWO");
myStoredProcedureCall.setString(9, "NINE");
ResultSet paramResults = myStoredProcedureCall.executeQuery();
Run Code Online (Sandbox Code Playgroud)

然后我抛出了这个SQLException:

*** SQLException caught ***
SQLState: JZ0SA
Message:  JZ0SA: Prepared Statement: Input parameter not set, index: 2.
Vendor:   0
Run Code Online (Sandbox Code Playgroud)

对于我想要做的一些背景知识,我需要创建一个流程,从IBM MQ流中接收有关产品的信息,然后在第三个应用程序中创建产品.第三方应用程序使用Sybase来存储它的数据,并创建一个产品,我需要调用一个包含大约130个参数的存储过程.对于我需要创建的产品类型,只需要设置其中约15个参数,其余参数将保留为默认值.

我考虑的选项是:

  • 创建仅设置我需要的值的自定义存储过程,然后调用第三方产品sproc.
  • 为Java中的所有参数设置默认值.

当然必须有一个更简单的方法来做到这一点?

java sybase stored-procedures jdbc callable-statement

4
推荐指数
1
解决办法
2万
查看次数

Java CallableStatement registerOutParameter,它有什么作用?

我正在遵循有关可调用语句的指南。

在本指南中,它说我需要使用以下语句注册 out 参数:

callsts.registerOutParameter(2, java.sql.Types.VARCHAR);
Run Code Online (Sandbox Code Playgroud)

问题:为什么我需要这样做/它有什么作用?

完整的Java代码:

String getcall = "{call gettitle (?,?)}";
CallableStatement callsts = connect.prepareCall(getcall);
int nID = 15;
callsts.setInt(1, nID);
callsts.registerOutParameter(2, java.sql.Types.VARCHAR);
callsts.execute();
String calltitle = callsts.getString(2);
System.out.println("Callable Stamement Title: "+calltitle);       
Run Code Online (Sandbox Code Playgroud)

mySQL程序:

DELIMITER $$ 
DROP PROCEDURE IF EXISTS `nothingtowear`.`gettitle` $$
CREATE PROCEDURE  `nothingtowear`.`gettitle` (
IN nothingtowear_ID INT,
OUT nothingtowear_TITLE VARCHAR( 255 )) 
BEGIN 
SELECT Title INTO nothingtowear_TITLE
FROM articles
WHERE ID = nothingtowear_ID;
END $$
DELIMITER;
Run Code Online (Sandbox Code Playgroud)

java mysql callable-statement

4
推荐指数
1
解决办法
4万
查看次数

来自Java的Oracle.对象参数的CallableStatement和Null?

我已经开始了,一个相当复杂的存储过程开始归结为一个非常简单的用例,似乎没有像我期望的那样工作.

现在,对于我的测试,存储过程看起来像这样:

CREATE OR REPLACE PROCEDURE proc_test(
v_someString varchar2
                      ) as
BEGIN
    dbms_output.put_line('test');
END;
Run Code Online (Sandbox Code Playgroud)

我可以使用可调用语句API从java调用此存储过程

java.sql.CallableStatement stmt = conn.prepareCall("call proc_test(?)");
stmt.setObject(1,null);
stmt.execute();
Run Code Online (Sandbox Code Playgroud)

以上作品已经过了.该方法执行并成功完成.现在它变得棘手.我们已经创建了一组oracle对象类型,以允许我们传递更复杂的结构,类似于以下内容

CREATE OR REPLACE
type SOMETYPE_TYPE force  UNDER BASE_TYPE (value varchar2(255),
CONSTRUCTOR FUNCTION SOMETYPE_TYPE RETURN SELF AS RESULT) NOT FINAL;
Run Code Online (Sandbox Code Playgroud)

如果我只是将程序更改为接受这些类型作为参数,如下所示:

CREATE OR REPLACE PROCEDURE proc_test(
v_someString SOMETYPE_TYPE 
                      ) as
BEGIN
    dbms_output.put_line('test');
END;
Run Code Online (Sandbox Code Playgroud)

甲骨文将打破 PLS-00306: wrong number or types of arguments in call to 'CNV_CREATE_PERSON'

是什么赋予了?如果我从另一个以null为值的过程调用此过程,它可以正常工作.只从java API调用它才会中断.

我一直在搜索任何解决方案的文档,但找不到.也许你们中的一位聪明才智的学者可以指出我正确的方向.

谢谢

java oracle callable-statement

4
推荐指数
1
解决办法
1万
查看次数

如何从单个CallableStatement获得多个结果集?

当我从命令行调用存储过程时,我得到以下内容.

CALL `events`.`get_event_by_id`(10)

+---------+----------+-------------+---------------------+---------------------+---------------------+--------+----------+
| evet_id | name     | description | starttime           | endtime             | last_modified       | active | addre_id |
+---------+----------+-------------+---------------------+---------------------+---------------------+--------+----------+
|      10 | samole 3 | sanely      | 2013-11-27 17:37:00 | 2013-11-27 18:09:00 | 2013-11-27 09:37:42 |      1 |       20 |
+---------+----------+-------------+---------------------+---------------------+---------------------+--------+----------+
1 row in set (0.00 sec)

+---------+------------+---------+
| user_id | username   | picture |
+---------+------------+---------+
|       1 | jamess2000 | NULL    |
|       2 | yferna2012 | NULL    |
+---------+------------+---------+
2 rows in set (0.00 sec) …
Run Code Online (Sandbox Code Playgroud)

java mysql callable-statement

2
推荐指数
1
解决办法
2万
查看次数

PostgreSQL CallableStatement:偏移量为6的格式错误的函数或过程转义语法

我在Java应用程序中使用CallableStatement调用Postgres存储函数时出错.错误如下:

org.postgresql.util.PSQLException: Malformed function or procedure escape syntax at offset 6.
    at org.postgresql.jdbc2.AbstractJdbc2Statement.modifyJdbcCall(AbstractJdbc2Statement.java:2390)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.<init>(AbstractJdbc2Statement.java:149)
    at org.postgresql.jdbc3.AbstractJdbc3Statement.<init>(AbstractJdbc3Statement.java:40)
    at org.postgresql.jdbc3g.AbstractJdbc3gStatement.<init>(AbstractJdbc3gStatement.java:26)
    at org.postgresql.jdbc3g.Jdbc3gStatement.<init>(Jdbc3gStatement.java:28)
    at org.postgresql.jdbc3g.Jdbc3gPreparedStatement.<init>(Jdbc3gPreparedStatement.java:21)
    at org.postgresql.jdbc3g.Jdbc3gCallableStatement.<init>(Jdbc3gCallableStatement.java:17)
    at org.postgresql.jdbc3g.Jdbc3gConnection.prepareCall(Jdbc3gConnection.java:45)
    at org.postgresql.jdbc3.AbstractJdbc3Connection.prepareCall(AbstractJdbc3Connection.java:316)
    at org.postgresql.jdbc2.AbstractJdbc2Connection.prepareCall(AbstractJdbc2Connection.java:203)
    at com.mchange.v2.c3p0.impl.NewProxyConnection.prepareCall(NewProxyConnection.java:632)
    at zm.co.freight.model.user.UserRoleModel.getUserRoleDocumentPermission(UserRoleModel.java:212)
Run Code Online (Sandbox Code Playgroud)

应该注意的是,我使用的是Postgres 9.2,posgresql-9.1-902.jdbc3.jar和c3p0-0.9.2-pre4.jar连接池.

这是我想要调用的存储函数:

CREATE OR REPLACE FUNCTION user_role_document_permission_select_all_per_user_role(userroleidin integer)
  RETURNS refcursor AS
$BODY$
declare
    mycurs refcursor;
begin
    open mycurs for
        select document._name,
          document_user_role_permission.viewing,
          document_user_role_permission.processing,
          document_user_role_permission.editing,
          document_user_role_permission.updating,
          document_user_role_permission.user_role_id,
          document_user_role_permission.document_id
       from document_user_role_permission, document where document_user_role_permission.document_id = document.id and document_user_role_permission.user_role_id =  userroleidin;
    return mycurs;
end;
$BODY$
  LANGUAGE plpgsql …
Run Code Online (Sandbox Code Playgroud)

postgresql jdbc callable-statement

1
推荐指数
1
解决办法
2593
查看次数

Java - MySQL调用存储过程

我正在尝试从Java调用存储过程.但是,我所做的是寻找一个功能.我错过了什么?这是我到目前为止所尝试的内容;

open();

try {

    statement = conn.prepareStatement(StringConstant.PROC_GET_POSITIONS);
    ResultSet resultSet = statement.executeQuery();

    while( resultSet.next() ){

        System.out.println(resultSet.getString(0));

    }

} catch ( SQLException sqlEx ) {
    sqlEx.printStackTrace();
}

close();
Run Code Online (Sandbox Code Playgroud)

抛出这个例外;

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: FUNCTION test.get_positions does not exist
Run Code Online (Sandbox Code Playgroud)

这是存储过程的编写方式(这是为了测试):

CREATE FUNCTION get_positions(OUT o_position VARCHAR(25))
BEGIN

  SELECT pos_name
  INTO o_position
  FROM master_position;

END;
Run Code Online (Sandbox Code Playgroud)

我提出这个问题的原因是SO建议这个标题:

-automate调用存储过程1
- 如何在MySQL中的存储过程中调用存储过程1
在Hibernate中 调用存储过程
2
从存储过程中调用存储过程和/或使用COUNT 2 -mysql存储过程调用hibernate 2

没有人回答我的问题.

java mysql stored-procedures callable-statement

1
推荐指数
1
解决办法
2万
查看次数

使用 statement.setArray() 将 Scala Option[List[_]] 传递给 Java JDBC Array

我正在尝试构建从 Scala 到 JDBC callableStatements 的接口。在大多数情况下,它很简单,除了Lists.

我需要能够采用List某种类型的 Scala ,并将其转换为可以传递给的 Java 数组,statement.setArray(type, array)但我没有任何运气(部分是因为我不太了解 Java 和 JDBC)。

这是我想要做的:

for (parameter <- ps.parameters) {
    case GPArrayIn(None, t) => callableStatement.setNull(index, t)
    case GPIn(v: Some[_], Types.INTEGER) => callableStatement.setInt(index, v.get.asInstanceOf[Int])
    case GPIn(v: Some[_], Types.VARCHAR | Types.LONGVARCHAR) => callableStatement.setString(index, v.get.asInstanceOf[String])
    case GPArrayIn(v: Some[List[_]], Types.INTEGER) => callableStatement.setArray(Types.INTEGER, ???? )
    case GPArrayIn(v: Some[List[_]], Types.VARCHAR | Types.LONGVARCHAR) => callableStatement.setArray(Types.VARCHAR, ???? )
    ...
Run Code Online (Sandbox Code Playgroud)

对于简单的值,这非常简单,但是当涉及到setArray()调用时,我被卡住了。

任何建议将不胜感激。被困在这几个小时......

java arrays scala jdbc callable-statement

1
推荐指数
1
解决办法
1679
查看次数

如何使用 callablestatement 调用“视图”

我以为这将是一个简单的谷歌搜索,但我找不到答案:

我正在将 Access 数据库移至 SQL Server,我已将一些查询转换为视图。我的 Java 应用程序过去使用简单的方式调用每个查询:

{ call dbo.GetOtherRanges() } //Well, not entirely true - Access did not use 'dbo' schema in front of the name
Run Code Online (Sandbox Code Playgroud)

这适用于存储过程。但是当我对视图执行此操作时,我收到以下信息:

[SQL Server]The request for procedure 'GetOtherRanges' failed because 'GetOtherRanges' is a view object.
Run Code Online (Sandbox Code Playgroud)

我认为这就像删除()视图名称后面的括号一样简单,但这并没有达到目的。

  • 如何使用 JDBC CallableStatment“调用”视图?
  • 是否还有调用表值函数的不同方法?

java sql jdbc callable-statement

0
推荐指数
1
解决办法
7553
查看次数