【问题标题】:update query with optional parameres使用可选参数更新查询
【发布时间】:2020-10-29 18:36:57
【问题描述】:

我正在尝试使用可选参数更新行,但下面的查询出现错误。

@Modifying
@Transactional
@Query("UPDATE Visit visits SET "
        + " visits.approvalStatus is null OR visits.approvalStatus = :approvalStatus "
        + " , visits.declineReason is null OR visits.declineReason =:declineReason "
        + " WHERE visits.visitId in :visitIds ")
public int patchUpdate(@Param("approvalStatus") String approvalStatus,
        @Param("declineReason") String declineReason, @Param("visitIds") List<Integer> visitIds);

错误日志:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting EQ, found 'is' near line 1, column 69 [UPDATE com.quest.vms.entity.Visit visits SET  visits.approvalStatus is null OR visits.approvalStatus = :approvalStatus  WHERE visits.visitId in :visitIds ]

编辑添加信息:这里我想在新数据不为空时更新特定字段,否则应忽略该参数。

感谢您的帮助

【问题讨论】:

  • 您在此查询中的意图是什么?如果它不为空,您是否尝试更新approvalStatus?
  • 是的@Shawrup,我只在字段不为空时才更新字段,我还有一些其他字段要添加到此查询中
  • 我只在字段不为空时才更新字段你的意思是现有的approvalStatus不为空还是新数据不为空?
  • 新数据不为空时
  • 也许在where条件下添加and :approvalStatus is not null就足够了

标签: java spring-boot jpa spring-data-jpa


【解决方案1】:

is null 用于检查字段。 根据条件设置列,您可以使用:

UPDATE Visit visits SET "
        + "  visits.approvalStatus = CASE "
        + " WHEN visits.visitId in :visitIds THEN :approvalStatus "
        + " ELSE NULL "
        + " END"

【讨论】:

    【解决方案2】:

    UPDATE 查询中存在语法错误,缺少设置字段值的部分。

    使用COALESCE 函数的查询(或使用IsNullNullIfNVL 等函数的本机查询)可能会有所帮助:

    @Query("UPDATE Visit visits SET "
         + "visits.approvalStatus = COALESCE(:approvalStatus, approvalStatus) "
         + "visits.declineReason = COALESCE(:declineReason, declineReason) "
         + " WHERE visits.visitId in :visitIds")
    public int patchUpdate(
        @Param("approvalStatus") String approvalStatus,
        @Param("declineReason") String declineReason, 
        @Param("visitIds") List<Integer> visitIds
    );
    

    或者使用类似的CASE声明

    @Query("UPDATE Visit visits SET "
         + "visits.approvalStatus = (CASE :approvalStatus WHEN NULL THEN approvalStatus ELSE :approvalStatus END) "
         + "visits.declineReason = (CASE :declineReason WHEN NULL THEN declineReason ELSE :declineReason END) "
         + " WHERE visits.visitId in :visitIds")
    public int patchUpdate(
        @Param("approvalStatus") String approvalStatus,
        @Param("declineReason") String declineReason, 
        @Param("visitIds") List<Integer> visitIds
    );
    

    【讨论】:

    • 我只想在传入的参数值不为空时更新,否则应该忽略
    • 这不是准确的答案,但对寻找解决方案最有帮助(使用 CASE)。谢谢
    • 还有一个问题:如果我的可选参数为空怎么办。如何验证传入布尔参数值的 null 值?
    • 我不太清楚你的意思。你可以使用Boolean 包装器而不是原始boolean 作为输入参数。
    【解决方案3】:

    您可以在设置数据时添加案例条件

    UPDATE 
        Visit visits 
    SET 
        visits.approvalStatus = (
            case 
                when :approvalStatus is null 
                then visits.approvalStatus 
                else :approvalStatus 
            end
        ),
        visits.declineReason = (
            case 
                when :declineReason is null 
                then visits.declineReason 
                else :declineReason 
            end
        ),
     WHERE visits.visitId in :visitIds
    

    如果传递的值为null,则设置db中的值,否则设置传递的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多