【问题标题】:Executing multiple procedure calls at once in jdbc在 jdbc 中一次执行多个过程调用
【发布时间】:2019-01-03 04:21:06
【问题描述】:

FYI, None of the solutions mentioned in this answer have worked for me。我打算在一个 sql 查询中执行多个过程调用。 Mysql代码是:

SET @SYSTEM_ID = (SELECT `id` FROM `users_admin` WHERE `username`='my_username');
SET @PAYMENT_MODE = 0;
CALL payment_mode_add(@SYSTEM_ID, 'TEST', TRUE, @PAYMENT_MODE);
CALL payment_add(@SYSTEM_ID, @PAYMENT_MODE, 
'receipt/00',1000.50,@TEMP_ID);

它应该工作的方式是,过程“payment_mode_add”设置了一个输出参数,该参数应该被过程“payment_add”用作输入参数。我知道在Java中一次执行多个查询是不可能的,但我打算在这里使用的方法在 PHP 等语言中效果很好。 payment_mode_add 的定义是:

# -- PAYMENT-MODE ADD
DELIMITER //
DROP PROCEDURE IF EXISTS `payment_mode_add` //
# -- remove above
CREATE PROCEDURE `payment_mode_add`(IN _author INT, IN _name VARCHAR(20), IN _active BOOLEAN, OUT _id INT)
BEGIN
    # -- declare
    IF NOT EXISTS (SELECT `id` FROM `users_admin` WHERE `id`=_author AND `active`=TRUE) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid Author'
    ELSEIF EXISTS (SELECT `id` FROM `gym_form_hhq` WHERE `name`=_name) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '\'Payment Mode\' already exists'
    ELSE
        SET _active = IFNULL(_active,FALSE)
        INSERT INTO `payment_mode`(`name`, `active`, `author`) 
                        VALUES ( _name , _active , _author )
        SET _id = LAST_INSERT_ID()
        SELECT * FROM `payment_mode` WHERE `id`=_id
    END IF
END //
DELIMITER ;

“payment_add”的定义:

# -- PAYMENT ADD
DELIMITER //
DROP PROCEDURE IF EXISTS `payment_add` //
# -- remove above
CREATE PROCEDURE `payment_add`(IN _author INT, IN _mode INT, IN _receipt VARCHAR(50), IN _amount FLOAT, OUT _id INT)
BEGIN
    # -- declare
    IF NOT EXISTS (SELECT `id` FROM `users_admin` WHERE `id`=_author AND `active`=TRUE) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid Author'
    ELSEIF NOT EXISTS (SELECT `id` FROM `payment_mode` WHERE `id`=_mode AND `active`=TRUE) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid Payment Mode'
    ELSE
        SET _receipt = IFNULL(_receipt, NOW())
        SET _amount = IFNULL(_amount, 0)
        INSERT INTO `payment`(`mode`, `reciept`, `amount`, `author`) 
                    VALUES   (_mode , _receipt , _amount , _author)
        SET _id = LAST_INSERT_ID()
        SELECT * FROM `payment` WHERE `id`=_id
    END IF
END

这只是我在 JDBC 中遇到的一些更复杂问题的基本示例。有什么方法可以通过 JDBC 或任何其他可以给我想要实现的输出的方法一次执行所有这 4 个查询?

【问题讨论】:

  • 能否创建一个过程来封装这个逻辑,然后通过 JDBC 调用它?
  • 正如我所提到的,我使用 PHP 来运行这些查询,希望它们也能在 JDBC 中完美运行。所以,我已经写了 50 多个这样的查询。如果没有选择,我将不得不改变我的整个结构,如果可能的话,这将是我打算避免的大量工作。
  • 在 JDBC 中可能没有什么开箱即用的功能。您可以查看Running a .sql script using MySQL with JDBC 的替代方案。
  • 我猜,这种方法会强制我将所有查询插入单独的文件中。这将使我的项目结构非常混乱。此外,这非常耗时。
  • 我认为标记的副本不正确@MarkRotteveel。这个问题是关于通过 JDBC 执行多个过程 SQL 语句(MySQL 方言)。在 Oracle 中,您可以通过将内容包装在匿名 PL/SQL 块中来做到这一点,但显然 MySQL 没有相同的功能。

标签: java mysql sql jdbc


【解决方案1】:

由于这个问题得到了很多人的支持并且我已经找到了解决方案,所以我正在回答它。

所以你所要做的就是编写一个方法,它接受一个字符串 sql 查询数组作为它的参数,一个一个地执行所有的查询(在数组中),并返回最后一个 ResultSet。示例:

public ResultSet runMutltipleQueries(String [] arrayOfQueries) throws SQLException{
    ResultSet rs = null;
    Statement stmnt= con.createStatement();
    boolean rsReturned=false;
    for(int i=0; i<arrayOfQueries.length;i++){
       rsReturned = stmnt.execute(arrayOfQueries[i]);
    }
    if(rsReturned){
        rs= stmnt.getResultSet();
    }

    return rs;

}

在调用方法时,

queries= new String [] {"SET @SYSTEM_ID = (SELECT `id` FROM `users_admin` WHERE `username`='"+model.getUserName()+"');",
                 "SET @TRANSACTION_ID = (select `user_data`.`transaction` from `user_data` where id= "+idText.getText()+");",
                 "SET @FREEZE_ID = NULL;",
                 // set payment id to 0 for now, update it in pay operation.
                 "SET @PAYMENT_ID = NULL;",
                 "CALL user_freeze_add(@SYSTEM_ID, @TRANSACTION_ID, '"+FreezeStartDate.getValue()+"', '"+FreezeStartDate.getValue().plusDays(Integer.parseInt(freezeAvailabletext.getText()))+"', @PAYMENT_ID, @FREEZE_ID);"
};

ResultSet rs= DatabaseHandler.getInstance().runMutltipleQueries(queries);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多