【问题标题】:How to execute multiple stored procedure queries from a file in Java?如何从 Java 中的文件执行多个存储过程查询?
【发布时间】:2018-12-13 16:01:49
【问题描述】:

我使用了多个 sql 查询来创建与我的项目相关的存储过程。这是我想在java中执行的sql文件(由多个存储过程查询组成):

# -- USER-ADMIN ADD
DELIMITER //
DROP PROCEDURE IF EXISTS `users_admin_add` //
# -- remove above
CREATE PROCEDURE `users_admin_add`(
IN _author INT,
IN _name VARCHAR(100),
IN _mobile VARCHAR(20),
IN _email VARCHAR(100),
IN _address TEXT,
IN _username VARCHAR(30),
IN _password TEXT,
IN _pin INT,
IN _preferred VARCHAR(20),
IN _active BOOLEAN,
IN _fired BOOLEAN,
IN _access INT,
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 `users_admin` WHERE `username`=_username) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Username Already exists';
ELSEIF EXISTS (SELECT `id` FROM `users_admin` WHERE `mobile`=_mobile) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Mobile Already registered';
ELSE
# -- null checks
SET _active = IFNULL(_active,FALSE);
SET _fired = IFNULL(_fired,FALSE);
SET _preferred = IFNULL(_preferred,'PASSWORD');
SET _access = IFNULL(_access,(SELECT `level` FROM `core_access_types` WHERE `name`='RECEPTIONIST'));

# -- main
INSERT INTO `users_admin`(`name`, `mobile`, `email`, `address`, `username`, `password`, `pin`, `preferred`, `active`, `fired`, `access`, `author`) 
VALUES ( _name,  _mobile,  _email,  _address,  _username,  _password,  _pin,  _preferred,  _active,  _fired,  _access,  _author); 
SET _id = LAST_INSERT_ID();
SELECT * FROM `users_admin` WHERE `id`=_id;
END IF;
END //
DELIMITER ;

# -- USER-ADMIN DELETE
DELIMITER //
DROP PROCEDURE IF EXISTS `users_admin_delete` //
# -- remove above
CREATE PROCEDURE `users_admin_delete`(
IN _author INT,
IN _user 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 `users_admin` WHERE `fired`=TRUE AND `id`=_user) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'This account has been disabled permanently';
ELSEIF NOT EXISTS (SELECT `id` FROM `users_admin` WHERE `id`=_user) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid User';
ELSE
UPDATE `users_admin` SET `fired`=TRUE, `modified_at`=NOW(), `modifier`=_author WHERE `id`=_user;
SELECT * FROM `users_admin` WHERE `id`=_user;
END IF;
END //
DELIMITER ;

我使用了 java 中的 addBatch() 和 executeBatch() 等方法,但它们似乎不起作用。 这是我最后使用的java代码。我已经尝试了更多方法,我想说,它们都没有奏效:

private static DatabaseHandler handler = null;
String uname="root";
String pass="";
String url="jdbc:mysql://localhost:17770/wdms_db?zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true";
private static Statement stmnt=null;
private static Connection con=null;

static String readFile(String path, Charset encoding) throws IOException 
{
  byte[] encoded = Files.readAllBytes(Paths.get(path));
  return new String(encoded, encoding);
}
private DatabaseHandler() throws SQLException {
    createsConnection();

    InputStream is = null;
    try {
        System.err.println("at procedures.sql---------------------------------------------------------------------");
        is = new FileInputStream("C:\\Users\\procedures.sql");
    } catch (FileNotFoundException ex) {
        Logger.getLogger(DatabaseHandler.class.getName()).log(Level.SEVERE, null, ex);
    }

    executeScript(con,is);
}

executeScript(con, is)的定义:

static void executeScript(Connection conn, InputStream in)
    throws SQLException
{
//     System.out.println(in);
    Scanner s = new Scanner(in);
    s.useDelimiter("/\\*[\\s\\S]*?\\*/|--[^\\r\\n]*|;");

    Statement st = null;

    try
    {
    st = conn.createStatement();

    while (s.hasNext())
    {
        String line = s.next().trim();

        if (!line.isEmpty())
            System.out.println(line);
            st.execute(line);
    }
    // st.executeBatch();
    }
    finally
    {
    if (st != null)
        st.close();
    }
}

【问题讨论】:

  • 您能提供如何从您的代码中执行此操作吗?如果您使用的是 CallableStatement,则无法批量执行。
  • @dush,我已经编辑了我的问题以提供更多详细信息。
  • 您正在从st.execute(line) 执行不完整的 sql 语句。您必须从文件中正确提取单个 sql 语句并将其提供给 st.execute(line)。生病发布一个例子

标签: java mysql sql jdbc callable-statement


【解决方案1】:

您正在从st.execute(line) 执行不完整的 SQL 语句。

如果您的 SQL 文件如下所示:

---
DROP PROCEDURE IF EXISTS `users_admin_add`
---
CREATE PROCEDURE `users_admin_add`(
IN _author INT,
IN _name VARCHAR(100),
IN _mobile VARCHAR(20),
IN _email VARCHAR(100),
IN _address TEXT,
IN _username VARCHAR(30),
IN _password TEXT,
IN _pin INT,
IN _preferred VARCHAR(20),
IN _active BOOLEAN,
IN _fired BOOLEAN,
IN _access INT,
OUT _id INT
)
BEGIN
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 `users_admin` WHERE `username`=_username) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Username Already exists';
ELSEIF EXISTS (SELECT `id` FROM `users_admin` WHERE `mobile`=_mobile) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Mobile Already registered';
ELSE
SET _active = IFNULL(_active,FALSE);
SET _fired = IFNULL(_fired,FALSE);
SET _preferred = IFNULL(_preferred,'PASSWORD');
SET _access = IFNULL(_access,(SELECT `level` FROM `core_access_types` WHERE `name`='RECEPTIONIST'));

INSERT INTO `users_admin`(`name`, `mobile`, `email`, `address`, `username`, `password`, `pin`, `preferred`, `active`, `fired`, `access`, `author`) 
VALUES ( _name,  _mobile,  _email,  _address,  _username,  _password,  _pin,  _preferred,  _active,  _fired,  _access,  _author); 
SET _id = LAST_INSERT_ID();
SELECT * FROM `users_admin` WHERE `id`=_id;
END IF;
END

应该使用如下分隔符

static void executeScript(Connection conn, InputStream in)
    throws SQLException
{
//     System.out.println(in);
    Scanner s = new Scanner(in);
    s.useDelimiter("---");

    Statement st = null;

    try
    {
    st = conn.createStatement();

    while (s.hasNext())
    {
        String line = s.next().trim();

        if (!line.isEmpty())
            System.out.println(line);
            st.execute(line);
    }
    // st.executeBatch();
    }
    finally
    {
    if (st != null)
        st.close();
    }
}

你也应该关闭扫描仪。

【讨论】:

  • com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException 它给出了这个错误。 @dush
  • 你使用了我上面提到的sql文件并将代码更改为s.useDelimiter("---")对吗?我在本地对此进行了测试并且工作正常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 2021-12-13
  • 2013-01-08
  • 2020-04-04
  • 2012-12-26
  • 1970-01-01
相关资源
最近更新 更多