当前位置: 首页 > 面试题库 >

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

微生恩
2023-03-14
问题内容

我正在使用JAVA和MySQL更新带有输入参数作为JSON输入的表。问题是我不知道输入中将存在和不存在所有参数,因此可以为某些参数获取空值。因此,当我运行更新查询时,数据库中的所有列都存储这些空值。我浏览了网络,并查看了各种堆栈解决方案。我发现这是一个经过测试的解决方案,但不适用于我。我对此并不陌生,因此愿意以其他任何方式实现这一目标:

 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避免设置空值并保留数据库的现有值,但是当它不具有空值而是实际值时,它就无法正常工作。我只是测试一列,即USER_TABLE_FIRST_NAME。而“用户”是我将输入发送为的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.html" target="_blank">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)

问题答案:

您将用户名直接插入SQL,而无需转义,甚至不加引号。我认为您只是错过了撇号。

为防止SQL注入问题,切勿从动态数据中插入SQL字符串常量,始终使用PreparedStatement并插入标记。

另外,可以转义值,但是使用标记更加安全,并允许数据库缓存已编译的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 + "'"变为null值,这绝对不是您想要的。A='Joe'``A='null'

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



 类似资料:
  • 问题内容: 我正在使用JAVA和MySQL更新带有输入参数作为JSON输入的表。问题是我不知道输入中将存在和不存在所有参数的情况,因此有可能获得某些参数的空值。因此,当我运行更新查询时,数据库中的所有列都将存储这些空值。我浏览了网络,并查看了各种堆栈上的解决方案。我发现这是一个经过测试的解决方案,但不适用于我。我对此并不陌生,因此我愿意以其他任何方式实现这一目标: 尽管IFNULL避免设置空值并保

  • 问题内容: 我有一个表,其中有一个带有默认值的列: 有一个存储过程插入到: 您可以看到,我必须有条件地分支以便我的插入使用默认值(如果为null)。仅一列就可以了,但是请考虑是否有更多列-语法可能很笨拙。 我是否可以使用一种语法来指定插入值应该返回默认值(如果为null)?我尝试了以下操作,但可以理解的是语法错误: 问题答案:

  • 只有当新值不为null时,我才会更新集合设置值。我有这样一个代码: 有没有一个简单的方法可以做到这一点? 另一种方法:如果我可以从我获取数据的表单的占位符中获取值,我可以解决这个问题...但是这可能吗?

  • 问题内容: 我想知道是否可以选择列的值(如果该列存在),否则选择null。换句话说,当列不存在时,我想“举起” select语句来处理这种情况。 注意,我正在巩固我的数据模型和设计。我希望在接下来的几周中排除这种逻辑,但是我真的想超越这个问题,因为数据模型修复比我现在想解决的要耗费更多时间。 另请注意,我希望能够在一个查询中执行此操作。所以我不是在寻找像这样的答案 首先检查子查询中的列。然后修改您

  • 在我的flutter应用程序中,我导入了flutter库。然而,这个库目前不支持flutter Web。图书馆不是我的应用程序使用的必要条件。 主要问题:是否有任何方法来检查导入的库是否不受支持,然后在这种情况下我可以删除部分UI和代码?

  • 问题内容: 我有这样的Mysql表 假设该表的示例数据ID 现在,如果组合或对(member_id,doc_id)存在,我想在该表中插入;否则,如果status为0,则更新状态。这是我使用的sql查询 它应该用数据2 1 2 1更新第二行 如果我插入这个 它应该插入一个新行,其数据为4 2 1 0 但我无法解决。而且我认为在innodb引擎中,member_id和doc_id被引用到另一个表的主键