如何在软件首次运行时从 java 代码创建 MySQL 过程(设置数据库过程))
How to create MySQL Procedures from java code when software runs for first time (Setting up database procedures))
当我的应用程序 运行 首次在新设备上运行时,我想设置我的数据库。为此,我必须创建必要的表、存储过程等。我在应用程序初始启动时成功创建了表。但是我无法对程序实施相同的操作。
我尝试在应用程序第一次启动时执行存储过程查询。尽管创建过程的 MySQL 代码是正确的,但是 Java 给出了一个错误
java.sql.BatchUpdateException:你的SQL语法有误;查看与您的 MySQL 服务器版本相对应的手册,了解在第 1 行 'DELIMITER // CREATE PROCEDURE update_registered_fields (IN _field VARCHAR(200))' 附近使用的正确语法
如果我 运行 在 MySQL webview 中使用相同的查询,它 运行 是完美的。
我没有在这里显示与数据库的连接,因为它工作正常。我已经使用 procedures.xml 文件来查询代码。
DatabaseHandler.java
private static void inflateProcedure() throws SQLException, FileNotFoundException, ParserConfigurationException, SAXException, IOException{
Set<String> set = new HashSet<>();
List<String> procedureData = new ArrayList<>();
String query = "SHOW PROCEDURE STATUS WHERE Db = '"+Preferences.getPreferences().getDatabaseName()+"';";
System.out.println(query);
stmnt = con.createStatement();
ResultSet rs = stmnt.executeQuery(query);
while(rs.next()){
set.add(rs.getString("NAME").toLowerCase());
}
System.out.println("Already Loaded Procedures "+set);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new FileInputStream(Preferences.getPreferences().getLocation()+"procedures.xml"));
NodeList nList = doc.getElementsByTagName("table-entry");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
Element entry = (Element) nNode;
String procedureName = entry.getAttribute("name");
String params = entry.getAttribute("params");
String procedureQuery = entry.getAttribute("data");
if (!set.contains(procedureName.toLowerCase())) {
procedureData.add(String.format("DELIMITER // CREATE PROCEDURE %s %s \n"
+ "BEGIN;\n"
+ " %s \n"
+ "END //\n DELIMITER ", procedureName, params, procedureQuery));
}
}
if (procedureData.isEmpty()) {
System.out.println("Procedures are already loaded");
}
else {
System.out.println("Inflating new Procedures.");
createProcedures(procedureData);
}
}
private static void createProcedures(List<String> procedureData) throws SQLException{
Statement statement = con.createStatement();
for (String command : procedureData) {
System.out.println(command);
statement.addBatch(command);
}
statement.executeBatch();
statement.close();
}
procedures.xml
<procedures>
<table-entry name="update_registered_fields" params="(IN _field VARCHAR(200))" data="DECLARE _value INT DEFAULT 0;
SET _value := (SELECT `user_register_feilds`.`last_used` FROM `user_register_feilds` WHERE `user_register_feilds`.`name` = _field);
UPDATE `user_register_feilds` SET `user_register_feilds`.`last_used` = _value+1 WHERE `user_register_feilds`.`name` = _field;"/>
<table-entry name="sort_fields" params="(IN _value INT(50))" data="SELECT * FROM user_enquiry ORDER BY last_used DESC, id ASC LIMIT _value;"/>
我想执行这个查询。我什至尝试过 allowMultiQueries
。我也想知道在我们第一次启动应用程序时,这是填充数据库的正确方法吗?
您似乎在 sql 查询中使用了定界符,您正试图在 JDBC 中 运行,这从您的错误消息中显而易见:java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER // CREATE PROCEDURE update_registered_fields (IN _field VARCHAR(200))' at line 1
.
尝试删除分隔符。原始 sql 中使用定界符。 JDBC 不需要分隔符。
当我的应用程序 运行 首次在新设备上运行时,我想设置我的数据库。为此,我必须创建必要的表、存储过程等。我在应用程序初始启动时成功创建了表。但是我无法对程序实施相同的操作。
我尝试在应用程序第一次启动时执行存储过程查询。尽管创建过程的 MySQL 代码是正确的,但是 Java 给出了一个错误
java.sql.BatchUpdateException:你的SQL语法有误;查看与您的 MySQL 服务器版本相对应的手册,了解在第 1 行 'DELIMITER // CREATE PROCEDURE update_registered_fields (IN _field VARCHAR(200))' 附近使用的正确语法
如果我 运行 在 MySQL webview 中使用相同的查询,它 运行 是完美的。
我没有在这里显示与数据库的连接,因为它工作正常。我已经使用 procedures.xml 文件来查询代码。
DatabaseHandler.java
private static void inflateProcedure() throws SQLException, FileNotFoundException, ParserConfigurationException, SAXException, IOException{
Set<String> set = new HashSet<>();
List<String> procedureData = new ArrayList<>();
String query = "SHOW PROCEDURE STATUS WHERE Db = '"+Preferences.getPreferences().getDatabaseName()+"';";
System.out.println(query);
stmnt = con.createStatement();
ResultSet rs = stmnt.executeQuery(query);
while(rs.next()){
set.add(rs.getString("NAME").toLowerCase());
}
System.out.println("Already Loaded Procedures "+set);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new FileInputStream(Preferences.getPreferences().getLocation()+"procedures.xml"));
NodeList nList = doc.getElementsByTagName("table-entry");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
Element entry = (Element) nNode;
String procedureName = entry.getAttribute("name");
String params = entry.getAttribute("params");
String procedureQuery = entry.getAttribute("data");
if (!set.contains(procedureName.toLowerCase())) {
procedureData.add(String.format("DELIMITER // CREATE PROCEDURE %s %s \n"
+ "BEGIN;\n"
+ " %s \n"
+ "END //\n DELIMITER ", procedureName, params, procedureQuery));
}
}
if (procedureData.isEmpty()) {
System.out.println("Procedures are already loaded");
}
else {
System.out.println("Inflating new Procedures.");
createProcedures(procedureData);
}
}
private static void createProcedures(List<String> procedureData) throws SQLException{
Statement statement = con.createStatement();
for (String command : procedureData) {
System.out.println(command);
statement.addBatch(command);
}
statement.executeBatch();
statement.close();
}
procedures.xml
<procedures>
<table-entry name="update_registered_fields" params="(IN _field VARCHAR(200))" data="DECLARE _value INT DEFAULT 0;
SET _value := (SELECT `user_register_feilds`.`last_used` FROM `user_register_feilds` WHERE `user_register_feilds`.`name` = _field);
UPDATE `user_register_feilds` SET `user_register_feilds`.`last_used` = _value+1 WHERE `user_register_feilds`.`name` = _field;"/>
<table-entry name="sort_fields" params="(IN _value INT(50))" data="SELECT * FROM user_enquiry ORDER BY last_used DESC, id ASC LIMIT _value;"/>
我想执行这个查询。我什至尝试过 allowMultiQueries
。我也想知道在我们第一次启动应用程序时,这是填充数据库的正确方法吗?
您似乎在 sql 查询中使用了定界符,您正试图在 JDBC 中 运行,这从您的错误消息中显而易见:java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER // CREATE PROCEDURE update_registered_fields (IN _field VARCHAR(200))' at line 1
.
尝试删除分隔符。原始 sql 中使用定界符。 JDBC 不需要分隔符。