本机查询中未设置参数

Posted

技术标签:

【中文标题】本机查询中未设置参数【英文标题】:Parameters not being set in native query 【发布时间】:2018-02-09 11:04:00 【问题描述】:

我正在开发一个 SpringBoot 应用程序,我正在尝试使用以下命令进行简单删除:@Query(value="", nativeQuery = true)

我的查询有动态参数,但参数没有被替换,我在控制台上也没有收到任何错误。

我尝试了带有硬编码参数的 NativeQuery,它工作得非常好。

下面是代码:

@Repository
public interface TypGbPccRepo extends JpaRepository<TypGbPcc, String>    

@Transactional
@Modifying(ClearAutomatically = true)
@Query(value = "delete from T_ST_KFR__TYP_GB_PCC typ where  Trunc(typ.GUELTIG_AB) IN (?1) and typ.GB_PCC IN (?2)" , nativeQuery=true)
void deleteRecords(String datumStr , String gbPccStr);


我什至尝试了以下查询:

@Query(value = "delete from T_ST_KFR__TYP_GB_PCC typ where  Trunc(typ.GUELTIG_AB) IN (:datumStr ) and typ.GB_PCC IN (:gbPccStr)" , nativeQuery=true)
void deleteRecords(@Param("datumStr ") String datumStr , @Param("gbPccStr") String gbPccStr);

我要替换的参数:

datumStr - TO_DATE('12-Sep-2012', 'dd-MM-yy'), TO_DATE('14-Sep-2012', 'dd-MM-yy') gbPccStr - 'P0','P1'

我正在实现上述代码以删除基于组合主键的记录,该组合主键是GUELTIG_ABGB_PCC 的组合。如果可能的话,建议我如何使用查询 QueryMethod 来实现这一点?

我已经能够使用 QueryMethod 删除基于非复合主键的记录,但我无法为复合主键执行此操作。我必须一次删除多条记录。

下面是我的POJO

@Entity
@IdClass(TypGbPccId.class)
@Table(name="T_ST_KFR_TYP_GB_PCC")

public class  TypGbPcc implements Serializable


private static  final long serialVersionUID = .....

@Id
@Column(name="GB_PCC")
private String gbPcc = null ;

@Column(name="GB_PCC_desc")
priavte String gbPccDesc = null ;

@Column(name="GB_PCC_SQL")
priavte String gbPccSql = null ;

@Id
@Column(name="GUELTIG_AB")
@JsonFormat(pattern = "dd-MM-yyyy")
private String gueltigAb = null ;


setter & getter 在这里

【问题讨论】:

您的查询对我来说看起来不错。我想你可以尝试使用命名参数?例如@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname") User findByLastnameOrFirstname(@Param("lastname") String lastname, @Param("firstname") String firstname); 请参阅此处的文档:docs.spring.io/spring-data/jpa/docs/current/reference/html(示例 61。使用命名参数)。 我尝试使用它,但问题是,我将参数值创建为 String 并发送到 Repo,而我的 GUELTIG_AB 列之一是日期字段,因此它会引发不匹配错误跨度> PLease hellp.... *** 网络中的任何人 您以错误的方式使用它。它实际上会被替换,但会被您传入的文字字符串所取代......所以它将按字面意思插入'TO_DATE('12-Sep-2012' , 'dd-MM-yy'),TO_DATE('14-Sep-2012' , 'dd-MM-yy')',而不是作为 SQL 语句的一部分。基本上不会评估TO_DATE 【参考方案1】:

这些是绑定参数,它们与 SQL 语句分开传递到数据库。它们不用于创建带有连接参数的新 SQL 语句。

所以你的Trunc(typ.GUELTIG_AB) IN (?1) 与给定参数真正归结为:

丢弃GUELTIG_AB中的时间部分,使用系统默认格式将其转换为字符串,无论发生什么,并检查结果字符串是否包含在由单个字符串组成的列表中:" TO_DATE('12-Sep-2012' , 'dd-MM-yy'),TO_DATE('14-Sep-2012' , 'dd-MM-yy')"

你可能想要的更接近:

日期列表中的 GUELTIG_AB 元素具有两个元素 2014 年 9 月 12 日2014 年 9 月 14 日

因此,您的方法应如下所示:

@Modifying(ClearAutomatically = true)
@Query(value = "delete from T_ST_KFR__TYP_GB_PCC typ " + 
     "where  Trunc(typ.GUELTIG_AB) IN (?1) " + 
     "and typ.GB_PCC IN (?2)"
     , nativeQuery=true)
void deleteRecords(List<java.sql.Date> dates , List<String> gbPccStr);

注意:方法上不需要@Transactional注解,接口上也不需要@Repository注解。

我正在实现上述代码以删除基于组合主键的记录,该组合主键是GUELTIG_ABGB_PCC 的组合。如果可能的话,建议我如何使用查询 QueryMethod 来实现这一点?

这根本不是当前查询所做的。 如果您有具有以下键的行:

(d1,p1)
(d1,p2)
(d2,p1)
(d2,p2)

您不能使用这种方法删除例如(d1,p1)(d2,p2),因为它还会删除其他两个元素。

为了解决这个问题,在您的实体上声明 @IdClass。在您的存储库的类型参数中指定它并使用正常的查询方法。

【讨论】:

嗨@Jens——你是不是建议我将目前在字符串中的日期转换为 java.sql.date,将每个日期存储在 List 中,然后将其传递用 List GB_pcc 回购? 我已经有 Id 类,,,但我不知道如何在这种情况下使用 QueryMethod,非常感谢您的帮助... 关于第一条评论:假设 GUELTIG_AB 实际上是日期,是的,这就是我的建议。 关于第二个问题:看看github.com/spring-projects/spring-data-jpa/blob/…是否有帮助。如果不是,我建议为此创建一个新问题,因为它与 90% 的原始问题所问的主题确实不同。在那里您可以描述您在使用该方法时遇到的问题。【参考方案2】:

首先@Param("datumStr") 中的datumStr 后面有一个空格。接下来,将其类型更改为 List of String 并以您的默认 DB 日期格式传递日期字符串。

(您也应该将 gbPccStr 的类型更改为 List of Sting)

【讨论】:

【参考方案3】:

你可以这样做。

 @Query(value = "delete from TypGbPcc where  func('TRUNC',gueltigAb) IN func('TO_DATE',:dateOne,'dd/mm/yyyy') and
func('TRUNC',gueltigAb) IN func('TO_DATE',:dateTwo,'dd/mm/yyyy') and gbPcc IN (:gbPccStr)" , nativeQuery=true)
void deleteRecords(@Param("dateOne") String dateOne ,@Param("dateTwo") String dateTwo, @Param("gbPccStr") String gbPccStr);

在 dateOne 中给出第一个日期 在 dateTwo 中给出第二个日期

【讨论】:

以上是关于本机查询中未设置参数的主要内容,如果未能解决你的问题,请参考以下文章

本机查询问题

MySql 表列中未设置默认值

在 MS Access 2007 中未正确处理查询部分的日期类型的更新集

休眠。将字符串参数设置为 char 25

MyBatis 查询中未替换参数

使用 SQL ORACLE 在 CASE WHEN 中未获取记录时如何设置自定义值?