我这里有几个SQL查询 -
WITH emp AS
(SELECT 1 AS empid, 'Adam' AS ename, 10 AS deptno, 'Broker' AS description FROM dual
UNION ALL
SELECT 2, 'Bob', 20, 'Accountant' FROM dual
UNION ALL
SELECT 3, 'Charles', 30, 'Programmer' FROM dual
UNION ALL
SELECT 4, 'Dan', 10, 'Manager' FROM dual
UNION ALL
SELECT 5, 'Eric', 10, 'Salesman' FROM dual
UNION ALL
SELECT 6, 'Franc', 20, 'Consultant' FROM dual),
dept AS
(SELECT 10 AS deptno, 'Accounts' AS dname, 100 employment_type_id FROM dual
UNION ALL
SELECT 20, 'Broking', 100 FROM dual
UNION ALL
SELECT 30, 'Corporate Relations', 200 FROM dual),
employment_type AS
(SELECT 100 AS employment_type_id, 'Permanent' AS description FROM dual
UNION ALL
SELECT 200, 'Contract' FROM dual)
/* --- Query 1
select e.ename, d.dname, e.description
from emp e
inner join dept d on e.deptno = d.deptno
inner join employment_type e on d.employment_type_id = e.employment_type_id
-- */
-- /* Query 2
SELECT e.ename, d.dname, e.description
FROM employment_type e
INNER JOIN dept d ON e.employment_type_id = d.employment_type_id
INNER JOIN emp e ON d.deptno = e.deptno
-- */
;
Run Code Online (Sandbox Code Playgroud)
正如你可以在两个查询看到表的别名emp和employment_type是相同的,即e.
当我选择一个列时,我e.description不应该得到类似的错误
模糊列参考
Morevoer,两个查询的结果是不同的!在第一个中,emp.description在第二个中employment_type.description被选中,被选中.
请让我知道为什么会发生这种情况以及如何避免由此引起的混乱.
Oracle SQL 从未完全遵守任何 ANSI/ISO SQL 标准。例如,它从未AS支持from子句中支持:
select *from dual AS d; -- fails
Run Code Online (Sandbox Code Playgroud)
目前的合规性状态( Oracle 12c 的Oracle Compliance To Core SQL:2011)表明 ANSI SQL 的各种功能大多得到部分支持,例如:
...
E031, Identifiers:
Oracle supports this feature, with the following exceptions:
...
Run Code Online (Sandbox Code Playgroud)
或者,
E051, Basic query specification
Oracle fully supports the following subfeatures:
...
Run Code Online (Sandbox Code Playgroud)
虽然它没有说任何关于不明确的别名(或正式的范围变量)的信息,但您可能会想到差异很容易比页面中所述的更深。
我目前不知道如何让 Oracle 在这种情况下报告歧义,但在我看来,只要注意使别名清晰并不难。
您可能想知道 ANSI SQL 标准是否明确规定同一范围内不允许使用重复的别名。在SQL:2011 标准的SQL/Foundation 文档第 2 部分的第 7.6节中确实如此。(您可以从www.wiscorp.com下载该草案)。具体来说,在语法规则 10)小节中,它说(我删掉了一点):
10) Let RV be a range variable that is exposed by TR. Let RV1 be a range variable that is exposed by a <table reference> TR1 that has the same scope clause as TR.
a) If RV is a <table name>, then
i) If RV1 is a <table name>, then RV1 shall not be equivalent to RV.
ii) Otherwise, RV1 shall not be equivalent to the <qualified identifier> of RV.
b) Otherwise
i) If RV1 is a <table name>, then the <qualified identifier> of RV1 shall not be equivalent to RV.
ii) Otherwise, RV1 shall not be equivalent to RV.
Run Code Online (Sandbox Code Playgroud)
这里 RV 是可变范围,您可以看到最后一个选择适用于两个别名的情况。
我们知道主要的 SQL 品牌都实施了这项检查(SQL Server、MySQL、PostgreSQL),因此尽管这些信息只是草稿,但它应该是准确的。
| 归档时间: |
|
| 查看次数: |
233 次 |
| 最近记录: |