本机查询中未设置参数
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_AB
和GB_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_AB
和GB_PCC
的组合。如果可能的话,建议我如何使用查询 QueryMethod 来实现这一点?
这根本不是当前查询所做的。 如果您有具有以下键的行:
(d1,p1)
(d1,p2)
(d2,p1)
(d2,p2)
您不能使用这种方法删除例如(d1,p1)
和(d2,p2)
,因为它还会删除其他两个元素。
为了解决这个问题,在您的实体上声明 @IdClass
。在您的存储库的类型参数中指定它并使用正常的查询方法。
【讨论】:
嗨@Jens——你是不是建议我将目前在字符串中的日期转换为 java.sql.date,将每个日期存储在 List首先@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 中给出第二个日期
【讨论】:
以上是关于本机查询中未设置参数的主要内容,如果未能解决你的问题,请参考以下文章