如何修复 PL/SQL:ORA-00918:列在 Oracle 中定义不明确
How to fix PL/SQL: ORA-00918: column ambiguously defined in Oracle
我正在 Oracle 中创建一个包,当我编译了包的主体时,我收到了 PL/SQL: ORA-00918: column ambiguously defined 错误。
我已经检查了代码,并仔细检查了别名,所以我有点困惑为什么会收到此错误。
有问题的错误在第 10 行。
WHERE 子句中的 PERSON_CODE、FUND_YEAR 和 UIO_ID 是我在包中创建的函数的参数。
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = PERSON_CODE
AND LA.FUNDING_YEAR = FUND_YEAR
AND LA.UIO_ID = UIO_ID;
列 UIO_ID
缺少别名,只需提供 OU.UIO_ID
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = PERSON_CODE
AND LA.FUNDING_YEAR = FUND_YEAR
AND LA.UIO_ID = OU.UIO_ID;
将 table alais 与列名称一起使用总是好的做法。
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = <tableAlaisForPersonCode>PERSON_CODE
AND LA.FUNDING_YEAR = <tableAlaisForFUND_YEAR>FUND_YEAR
AND LA.UIO_ID = <tableAlaisForUIO_ID>UIO_ID;
您的函数参数名称和字段名称冲突,产生阴影效果。您可以在参数名称前加上函数名称以消除歧义
AND LA.UIO_ID = MyfunctionName.UIO_ID;
或者,重命名参数以避免此类事件的发生。
. The PERSON_CODE, FUND_YEAR and UIO_ID are the arguments on the function.
使用与列名相同的 PL/SQL 参数名是不好的做法。编译器应用最近的命名空间检查,这意味着在这种情况下它会尝试将 PERSON_CODE 映射到 table 列。别名是可选的,因此它不会意识到您正在尝试引用 PL/SQL 参数。
因为您有多个 table 并且有一列名为 PERSON_CODE,所以您会收到 ORA-00918 错误。否则你只会有一个返回所有行的查询。
更好的做法是用不同的方式命名参数;惯例是在它们前面加上 p_
:
WHERE LA.PERSON_CODE = P_PERSON_CODE
AND LA.FUNDING_YEAR = P_FUND_YEAR
AND LA.UIO_ID = P_UIO_ID;
我正在 Oracle 中创建一个包,当我编译了包的主体时,我收到了 PL/SQL: ORA-00918: column ambiguously defined 错误。
我已经检查了代码,并仔细检查了别名,所以我有点困惑为什么会收到此错误。
有问题的错误在第 10 行。 WHERE 子句中的 PERSON_CODE、FUND_YEAR 和 UIO_ID 是我在包中创建的函数的参数。
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = PERSON_CODE
AND LA.FUNDING_YEAR = FUND_YEAR
AND LA.UIO_ID = UIO_ID;
列 UIO_ID
缺少别名,只需提供 OU.UIO_ID
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = PERSON_CODE
AND LA.FUNDING_YEAR = FUND_YEAR
AND LA.UIO_ID = OU.UIO_ID;
将 table alais 与列名称一起使用总是好的做法。
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = <tableAlaisForPersonCode>PERSON_CODE
AND LA.FUNDING_YEAR = <tableAlaisForFUND_YEAR>FUND_YEAR
AND LA.UIO_ID = <tableAlaisForUIO_ID>UIO_ID;
您的函数参数名称和字段名称冲突,产生阴影效果。您可以在参数名称前加上函数名称以消除歧义
AND LA.UIO_ID = MyfunctionName.UIO_ID;
或者,重命名参数以避免此类事件的发生。
. The PERSON_CODE, FUND_YEAR and UIO_ID are the arguments on the function.
使用与列名相同的 PL/SQL 参数名是不好的做法。编译器应用最近的命名空间检查,这意味着在这种情况下它会尝试将 PERSON_CODE 映射到 table 列。别名是可选的,因此它不会意识到您正在尝试引用 PL/SQL 参数。
因为您有多个 table 并且有一列名为 PERSON_CODE,所以您会收到 ORA-00918 错误。否则你只会有一个返回所有行的查询。
更好的做法是用不同的方式命名参数;惯例是在它们前面加上 p_
:
WHERE LA.PERSON_CODE = P_PERSON_CODE
AND LA.FUNDING_YEAR = P_FUND_YEAR
AND LA.UIO_ID = P_UIO_ID;