Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果输入值不为null,则更新列,否则忽略并保留数据库中列的现有值_Java_Mysql_Sql_Sqlexception - Fatal编程技术网

Java 如果输入值不为null,则更新列,否则忽略并保留数据库中列的现有值

Java 如果输入值不为null,则更新列,否则忽略并保留数据库中列的现有值,java,mysql,sql,sqlexception,Java,Mysql,Sql,Sqlexception,我使用JAVA和MySQL更新一个表,其中输入参数作为JSON输入。问题是我不知道所有的参数都是什么 在输入中存在或不存在,因此可能会为某些对象获取空值 参数。因此,当我运行更新查询时,数据库中的所有列都存储这些空值。我浏览了网页,查看了stack上的各种解决方案。我发现这是一个经过测试的解决方案,但它不适合我。我不熟悉这一点,因此我愿意以任何其他方式实现这一点: String updateQuery = "UPDATE " + USER_TABLE + " SET " + USER_TABL

我使用JAVA和MySQL更新一个表,其中输入参数作为JSON输入。问题是我不知道所有的参数都是什么 在输入中存在或不存在,因此可能会为某些对象获取空值 参数。因此,当我运行更新查询时,数据库中的所有列都存储这些空值。我浏览了网页,查看了stack上的各种解决方案。我发现这是一个经过测试的解决方案,但它不适合我。我不熟悉这一点,因此我愿意以任何其他方式实现这一点:

 String updateQuery = "UPDATE " + USER_TABLE + " SET " + USER_TABLE_FIRST_NAME 
    + "=IFNULL("+ user.getFirstName() + "," + USER_TABLE_FIRST_NAME + ")," 
    + USER_TABLE_LAST_NAME + "='" + user.getLastName() + "'," 
    + USER_TABLE_ABOUT_ME + "='" + user.getAboutMe() + "',"
    + USER_TABLE_CITY + "='" + user.getCity() + "',"
    + USER_TABLE_DOB + "='" + user.getDateOfBirth() 
    + "' WHERE " + USER_TABLE_ID + "='" + user.getUserId() + "'";
尽管IFNULL避免设置null值并保留数据库的现有值,但当它没有null值时,它不会以另一种方式工作 价值,但实际价值。我只是在测试一列,即USER\u TABLE\u FIRST\u NAME。“user”是JSON对象,我将输入作为

    {
     "firstName":"Rakesh",
     "city":"Jaipur"
    }
它给出了以下错误:

 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'Rakesh' in 'field list'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1564)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1485)
at com.sports.jogar.services.UserService.updateUser(UserService.java:174)
at com.sports.jogar.resources.UserResource.updateUser(UserResource.java:72)
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:497)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:269)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:252)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1025)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:382)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:345)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:220)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1527)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1484)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

IFNULL
不会对您提供的变量执行null检查。请注意,您是字符串连接查询,而不是对字符串变量/对象本身调用
IFNULL

当您向
IFNULL
提供字符串时,它假定提供的字符串是
选择中的列名。因此,它正在寻找一个名为您提供的字符串的列,在本例中为“Rakesh”。因此,这是一个例外

IFNULL文档

您不能期望在业务逻辑层中调用
IFNULL
函数求值(您正在将SQL查询作为字符串进行连接和准备)。执行查询时,将在数据库中执行
IFNULL
函数

在您的情况下,考虑将IF-NULL逻辑移到业务逻辑并退出查询。计算各个组件属性并相应地组合SQL字符串

String updateQuery = "UPDATE " + USER_TABLE + " SET " ;
if(null != user.getFirstName()){
    updateQuery += " USER_TABLE_FIRST_NAME = '"+ user.getFirstName() + "'," ; 
}
if(null != user.getLastName() ){
    updateQuery += " USER_TABLE_LAST_NAME = '" + user.getLastName() + "'," ;
}
if(null != user.getAboutMe()){
    updateQuery += " USER_TABLE_ABOUT_ME = '" + user.getAboutMe() + "'," ;
}
if(null != user.getCity()){
    updateQuery += " USER_TABLE_CITY = '" + user.getCity() + "'," ;
}
if(null != user.getDateOfBirth() ){
    updateQuery += " USER_TABLE_DOB ='" + user.getDateOfBirth() + "'"; 
}
updateQuery += " WHERE " + USER_TABLE_ID + "='" + user.getUserId() + "'";

您正在将用户名直接插入SQL,而无需转义甚至引用。我想你只是错过了撇号

要防止SQL注入问题,请不要从动态数据中插入SQL字符串常量,始终使用PreparedStatement和insert标记

或者,转义值,但使用标记更安全,并通过允许数据库缓存已编译的SQL语句来提高SQL性能

String updateQuery = "UPDATE " + USER_TABLE +
                       " SET " + USER_TABLE_FIRST_NAME + "=IFNULL(? ," + USER_TABLE_FIRST_NAME + ")," +
                                 USER_TABLE_LAST_NAME + "=?," +
                                 USER_TABLE_ABOUT_ME + "=?," +
                                 USER_TABLE_CITY + "=?," +
                                 USER_TABLE_DOB + "=?" +
                     " WHERE " + USER_TABLE_ID + "=?";
PreparedStatement stmt = conn.prepareStatement(updateQuery);
stmt.setString(1, user.getFirstName());
stmt.setString(2, user.getLastName());
stmt.setString(3, user.getAboutMe());
stmt.setString(4, user.getCity());
stmt.setString(5, user.getDateOfBirth());
stmt.setString(6, user.getUserId());
注意:答案扩展以涵盖空检查问题

当您使用简单的字符串注入时,
“A=”“+name+”
对于非空值变成了
A='Joe'
,但是对于空值变成了
A='null'
,这绝对不是您想要的


通过使用参数标记,
的值可以是
null
,这意味着
IFNULL(?,Name)
将给出所需的确切行为,即当值不为null时使用
的值,当
为null时使用
Name
的值。

这不是问题的答案。答案是SQL不好,因为他忘了引用用户名。另外,请不要继续将字符串直接注入SQL而不转义这种糟糕的编码风格。请解释下投票。如果用户名为O'Malley,那么这里(到目前为止)的所有其他代码示例都将失败。转义特殊字符不是问题的关键。OP需要IFNULL来确定user.getFirstName()是否为NULL。在您的回答中,在USER.getFirstName返回null的场景中,第2行是
设置USER\u TABLE\u FIRST\u NAME=USER\u TABLE\u FIRST\u NAME
。这就是我对问题的理解。在安德烈亚斯编辑了他的答案后,我认为他的解决方案是正确的。它可以工作并且抵抗sql注入攻击。