Sql 混合隐式连接和显式连接
我在Hibernate生成无效SQL时遇到问题。具体来说,混合和匹配隐式和显式联接。这似乎是一个问题 但是,我不确定为什么这是无效的SQL。我提出了一个小玩具示例,它生成了相同的语法异常 模式 数据 工作SQL 这两个查询都有效。我意识到有一个笛卡尔积;那是故意的 显式联接: 隐式联接: 无效SQL 此查询在MSSQL 2000/2008或MySQL上不起作用:Sql 混合隐式连接和显式连接,sql,hibernate,join,cartesian-product,cross-join,Sql,Hibernate,Join,Cartesian Product,Cross Join,我在Hibernate生成无效SQL时遇到问题。具体来说,混合和匹配隐式和显式联接。这似乎是一个问题 但是,我不确定为什么这是无效的SQL。我提出了一个小玩具示例,它生成了相同的语法异常 模式 数据 工作SQL 这两个查询都有效。我意识到有一个笛卡尔积;那是故意的 显式联接: 隐式联接: 无效SQL 此查询在MSSQL 2000/2008或MySQL上不起作用: SELECT e1.name, e2.name, e1Manager.name FROM Empl
SELECT e1.name,
e2.name,
e1Manager.name
FROM Employee e1,
Employee e2
INNER JOIN Employee e1Manager
ON e1.managerEmployeeID = e1Manager.employeeID
在MS2000中,我得到一个错误:
列前缀“e1”不匹配
使用表名或别名
在查询中
在MySQL中,错误是:
未知列“e1.managerEmployeeID”
在“on子句”中
问题
为什么这个语法无效?
额外好处:有没有办法强制Hibernate只使用显式连接?
它会导致错误,因为根据SQL标准,JOIN关键字的优先级高于逗号。关键点在于,在FROM子句中计算相应的表之前,表别名不可用 所以,当您在表达式的JOIN…中引用e1时,e1还不存在 我正在研究Hibernate,请稍候,看看您是否能说服它在所有情况下都使用JOIN
嗯,Hibernate.org上的所有内容似乎都被重定向到jboss.org。所以现在没有办法在线阅读HQL文档。我相信他们最终会找到自己的名字的。PostgreSQL也给出了一个错误:
ERROR: invalid reference to FROM-clause entry for table "e1"
LINE 7: ON e1.managerEmployeeID = e1Manager.employeeID;
^
HINT: There is an entry for table "e1", but it cannot be referenced from this part of the query.
我认为问题在于,在这种情况下,当您连接两个表a和b e2和e1Manager时,您只能在ON子句中引用这两个表。因此,您可以在本ON子句中引用e2和e1Manager,但不能引用e1
我认为这是一种扩展,因此如果您有一个JOIN语句链,那么您可以在ON子句中引用同一链中的其他表,但不能交叉,。所以像'a在a.a_id=b.a_id上加入b在c.b_id=b.b_id和c.a_id=a.a_id上加入c这样的东西是允许的
您用于生成此SQL的HQL是什么?类似于从Employee e1、Employee e2中选择e1.name、e2.name、e1.manager.name之类的内容?这可能有点离题,因为它与hibernate无关,但来自的评论确实让我大开眼界。您需要先进行显式连接,而不是先编写隐式连接。如果有多个隐式联接,则此语法尤其有趣 在MS SQL中检查以下示例。并非所有联系人都定义了国家代码,但所有联系人都有一个属性val,该属性将在表Tbl中查找。因此,直观的解决方案不起作用:
SELECT * FROM
contacts, Tbl
LEFT OUTER JOIN country ON CtryCod = country.CtryCod
WHERE val = Tbl.val
相反,您可能更希望使用以下语法:
SELECT * FROM
contacts LEFT OUTER JOIN country ON CtryCod = country.CtryCod,
Tbl
WHERE val = Tbl.val
从候选人a中选择a.id、a.category.id、a.category.name、a.owner,其中category和owner是关联。真正重要的是,如果您将所有者放在第一位,它会起作用,这是由于连接的幸运重新排序。基于问题的快速重现,您可能希望尝试不混合选择实体和属性:选择a.id、a.category、a.owner或a.id、a.category.id、a.category.name,a.owner.id-这两个选项都为我生成了有效的SQL,但是您的HQL生成了无效的SQL,正如您为我所说的,我通常只获取候选对象,让Hibernate根据需要自动加载类别和所有者。或者使用left-join-fetch急切地获取它们。这是否回答了您的问题?
SELECT e1.name,
e2.name,
e1Manager.name
FROM Employee e1,
Employee e2
INNER JOIN Employee e1Manager
ON e1.managerEmployeeID = e1Manager.employeeID
ERROR: invalid reference to FROM-clause entry for table "e1"
LINE 7: ON e1.managerEmployeeID = e1Manager.employeeID;
^
HINT: There is an entry for table "e1", but it cannot be referenced from this part of the query.
SELECT * FROM
contacts, Tbl
LEFT OUTER JOIN country ON CtryCod = country.CtryCod
WHERE val = Tbl.val
SELECT * FROM
contacts LEFT OUTER JOIN country ON CtryCod = country.CtryCod,
Tbl
WHERE val = Tbl.val