为什么我的 PreparedStatement SQL 查询不起作用?仅适用于硬编码字符串
Why doesn't my PreparedStatement SQL query work? Only works with a hardcoded string
我正在尝试使用 PreparedStatement
生成 SQL 查询。当我使用硬编码 String
或串联时它工作得很好,但我完全不知道为什么它在使用 PreparedStatement
.
时不起作用
public Customer createCustomer(Customer customer) {
//Ommitted code
int result = statement.executeUpdate(createPreparedStatementQuery(customer), Statement.RETURN_GENERATED_KEYS)
);
使用 PreparedStatement 创建查询
public static String createPreparedStatementQuery(Customer customer){
String query = "INSERT INTO customers(Customer_Name, Address, Postal_Code, Phone, Created_By, Last_Updated_By, Division_ID) " +
"VALUES (?, ?, ?, ?, ?, ?, (SELECT Division_ID FROM first_level_divisions WHERE division = ?));";
try {
PreparedStatement statement = ConnectionManager.getConnection().prepareStatement(query);
statement.setString(1, customer.getName());
statement.setString(2, customer.getAddress());
statement.setString(3, customer.getPostalCode());
statement.setString(4, customer.getPhoneNumber());
statement.setString(5, customer.getCreatedBy());
statement.setString(6, customer.getLastUpdatedBy());
statement.setString(7, customer.getDivision());
System.out.println(statement); //Successfully returns the query
return statement.toString();
}catch (SQLException e){
System.out.println(e.getMessage());
return null;
}
}
这给出了错误:
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 'com.mysql.cj.jdbc.ClientPreparedStatement: INSERT INTO
customers(Customer_Name, ' at line 1
但是,对于通过连接或硬编码创建的字符串,查询执行得非常好。
public static String createConcatQuery(Customer customer) {
String query = "INSERT INTO customers(Customer_Name, Address, Postal_Code, Phone, Created_By, Last_Updated_By, Division_ID) " +
"VALUES ('"
+ customer.getName() + "', '"
+ customer.getAddress() + "', '"
+ customer.getPostalCode() + "', '"
+ customer.getPhoneNumber() + "', '"
+ customer.getCreatedBy() + "', '"
+ customer.getLastUpdatedBy() + "', "
+ "(SELECT Division_ID FROM first_level_divisions WHERE division = '"
+ customer.getDivision() + "'));";
System.out.println(query);
return query;
}
String hardCodedQuery = "INSERT INTO customers(Customer_Name, Address, Postal_Code, Phone, Created_By, Last_Updated_By,
Division_ID) VALUES ('ee', 'ee', 'ee', 'ee', 'test', 'test', (SELECT Division_ID FROM
first_level_divisions WHERE division = 'Newfoundland and Labrador'));";
我已经复制并粘贴了从日志中输出的两个查询。 concat 查询和 preparedstatement 查询都 return 相同的 String:
我完全不明白为什么它此时不起作用。有人可以帮我弄清楚我在使用 PreparedStatement
时做错了什么吗?
完整的 StackTrace:
java.sql.SQLSyntaxErrorException: 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 'com.mysql.cj.jdbc.ClientPreparedStatement: INSERT INTO customers(Customer_Name, ' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1337)
at com.mysql.cj.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2117)
at com.mysql.cj.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1342)
at sample.data.CustomerRepository.createCustomer(CustomerRepository.java:144)
at sample.controller.CustomerController.createCustomer(CustomerController.java:165)
at sample.controller.CustomerController.confirmAlert(CustomerController.java:153)
at sample.controller.CustomerController.onBtnSaveClick(CustomerController.java:146)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
您必须在 createPreparedStatementQuery()
函数中调用 statement.executeQuery()
。或者您可以 return 来自 createPreparedStatementQuery()
函数的语句对象并在 createCustomer()
.
中调用 statement.executeQuery()
N.B。您可以根据需要使用 statement.executeUpdate()
或 statement.executeQuery()
。
您的 createPreparedStatementQuery()
基本上是在 return 原始查询中使用 ?将其标记为 createCustomer()
中的语句对象。外面的语句对象不知道你在里面的语句对象中设置的参数。
我正在尝试使用 PreparedStatement
生成 SQL 查询。当我使用硬编码 String
或串联时它工作得很好,但我完全不知道为什么它在使用 PreparedStatement
.
public Customer createCustomer(Customer customer) {
//Ommitted code
int result = statement.executeUpdate(createPreparedStatementQuery(customer), Statement.RETURN_GENERATED_KEYS)
);
使用 PreparedStatement 创建查询
public static String createPreparedStatementQuery(Customer customer){
String query = "INSERT INTO customers(Customer_Name, Address, Postal_Code, Phone, Created_By, Last_Updated_By, Division_ID) " +
"VALUES (?, ?, ?, ?, ?, ?, (SELECT Division_ID FROM first_level_divisions WHERE division = ?));";
try {
PreparedStatement statement = ConnectionManager.getConnection().prepareStatement(query);
statement.setString(1, customer.getName());
statement.setString(2, customer.getAddress());
statement.setString(3, customer.getPostalCode());
statement.setString(4, customer.getPhoneNumber());
statement.setString(5, customer.getCreatedBy());
statement.setString(6, customer.getLastUpdatedBy());
statement.setString(7, customer.getDivision());
System.out.println(statement); //Successfully returns the query
return statement.toString();
}catch (SQLException e){
System.out.println(e.getMessage());
return null;
}
}
这给出了错误:
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 'com.mysql.cj.jdbc.ClientPreparedStatement: INSERT INTO customers(Customer_Name, ' at line 1
但是,对于通过连接或硬编码创建的字符串,查询执行得非常好。
public static String createConcatQuery(Customer customer) {
String query = "INSERT INTO customers(Customer_Name, Address, Postal_Code, Phone, Created_By, Last_Updated_By, Division_ID) " +
"VALUES ('"
+ customer.getName() + "', '"
+ customer.getAddress() + "', '"
+ customer.getPostalCode() + "', '"
+ customer.getPhoneNumber() + "', '"
+ customer.getCreatedBy() + "', '"
+ customer.getLastUpdatedBy() + "', "
+ "(SELECT Division_ID FROM first_level_divisions WHERE division = '"
+ customer.getDivision() + "'));";
System.out.println(query);
return query;
}
String hardCodedQuery = "INSERT INTO customers(Customer_Name, Address, Postal_Code, Phone, Created_By, Last_Updated_By,
Division_ID) VALUES ('ee', 'ee', 'ee', 'ee', 'test', 'test', (SELECT Division_ID FROM
first_level_divisions WHERE division = 'Newfoundland and Labrador'));";
我已经复制并粘贴了从日志中输出的两个查询。 concat 查询和 preparedstatement 查询都 return 相同的 String:
我完全不明白为什么它此时不起作用。有人可以帮我弄清楚我在使用 PreparedStatement
时做错了什么吗?
完整的 StackTrace:
java.sql.SQLSyntaxErrorException: 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 'com.mysql.cj.jdbc.ClientPreparedStatement: INSERT INTO customers(Customer_Name, ' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1337)
at com.mysql.cj.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2117)
at com.mysql.cj.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1342)
at sample.data.CustomerRepository.createCustomer(CustomerRepository.java:144)
at sample.controller.CustomerController.createCustomer(CustomerController.java:165)
at sample.controller.CustomerController.confirmAlert(CustomerController.java:153)
at sample.controller.CustomerController.onBtnSaveClick(CustomerController.java:146)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
您必须在 createPreparedStatementQuery()
函数中调用 statement.executeQuery()
。或者您可以 return 来自 createPreparedStatementQuery()
函数的语句对象并在 createCustomer()
.
statement.executeQuery()
N.B。您可以根据需要使用 statement.executeUpdate()
或 statement.executeQuery()
。
您的 createPreparedStatementQuery()
基本上是在 return 原始查询中使用 ?将其标记为 createCustomer()
中的语句对象。外面的语句对象不知道你在里面的语句对象中设置的参数。