2010-04-26 52 views
2

我需要在Hibernate中使用原生SQL查询并使用变量。如何在Hibernate中使用Mysql变量?

但休眠抛出一个错误说:空间参数前缀之后,是不允许

所以有与冲突:= mysql的变量赋值和休眠状态变量赋值。

这里是我的sql查询:

SET @rank:=0; 
UPDATE Rank SET [email protected]:[email protected]+1 ORDER BY Level; 

休眠代码(JPA语法):

Query query = em.createNativeQuery(theQuery); 
query.executeUpdate(); 

我不能使用存储过程,因为是动态生成的我的SQL查询('水平'可以'int'或'force'...)

我该怎么做?

感谢

+0

请添加Hibernate代码。 – 2010-04-26 10:49:17

+0

我刚刚添加了它,但这是一个非常简单的常见案例 – 2010-04-26 12:25:53

+1

您并不孤单, https://forum.hibernate.org/viewtopic.php?f=1&t=992931&start=0 http:// opensource。 atlassian.com/projects/hibernate/browse/HHH-2697 也许每个order by子句都有一个存储过程。 – 2010-04-26 13:02:19

回答

4

好了,我终于可以用存储过程(是的,我不想开始)至创建动态查询(我不认为这是可能的)。

这是我的代码: 存储过程:

DELIMITER | 

DROP PROCEDURE IF EXISTS UpdateRank | 

CREATE PROCEDURE UpdateRank(IN shortcut varchar(30)) 
BEGIN 
    SET @rank=0; 
    SET @query=CONCAT('UPDATE Rank SET ', shortcut, '[email protected]:[email protected]+1 ORDER BY ', shortcut);  

    PREPARE q1 FROM @query; 
    EXECUTE q1; 
    DEALLOCATE PREPARE q1; 
END; 

| 
DELIMITER ; 

尖端是使用CONCAT函数来动态地创建在存储过程中的查询。

然后,调用程序中的经典休眠功能:

Query q = em.createNativeQuery("CALL updateRank('lvl')"); 
q.executeUpdate(); 
+1

确保防止sql注入。 – 2010-04-26 14:50:41

+0

是的,你是对的,但我已经保护它(我的快捷键只是字母) – 2010-04-26 17:01:11

+1

我发现更好的方法来解决这个问题与Hibernate拦截器http://stackoverflow.com/questions/9460018/how-can-i - 使用MySQL的指派,运营商在冬眠本地查询。如果有替代方案,我认为使用存储过程是非常糟糕的想法。 – 2012-02-29 02:34:24

0

使用MySQL Proxy重写查询休眠发送了查询数据库之后。

例如供应这种休眠,

UPDATE Rank SET rank_Level=incr(@rank) ORDER BY Level; 

但它改写此,

UPDATE Rank SET [email protected]:[email protected]+1 ORDER BY Level; 
+0

这是一个有点棘手... – 2010-04-26 14:38:11

+0

如何愚蠢是胡言乱语? – droope 2012-11-08 22:17:55

3

我会复制粘贴我的回答从https://stackoverflow.com/a/25552002/3987202

另一种解决方案对我们这些谁不能做跳跃到Hibernate 4.1。 3。
只需在查询中使用/*'*/:=/*'*/即可。 Hibernate代码将'之间的所有内容视为一个字符串(忽略它)。另一方面,MySQL将忽略blockquote中的所有内容,并将整个表达式评估为分配运算符。
我知道这是快速和肮脏的,但它得到的工作没有存储过程,拦截器等完成

+0

这给我修好了。谢谢! – 2016-06-21 19:35:37

相关问题