如何修复 PL/SQL:ORA-00918:Oracle 中定义的列不明确



我正在Oracle中创建一个包,当我编译包的主体时,我得到PL/SQL:ORA-00918:列定义不明确的错误。

我已经浏览了代码,并仔细检查了别名,所以对于为什么我会收到此错误有点困惑。

有问题的错误在第 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;

函数参数名称和字段名称冲突,从而产生阴影效果。您可以在参数名称前面加上函数名称以消除歧义

 AND LA.UIO_ID = MyfunctionName.UIO_ID;

或者,重命名参数以避免此类事件。

表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;

.PERSON_CODE、FUND_YEAR 和 UIO_ID 是函数的参数。

使用与列名相同的 PL/SQL 参数名称是一种不好的做法。编译器应用最近的命名空间检查,这意味着在这种情况下,它会尝试将PERSON_CODE映射到表列。别名是可选的,因此它不会意识到您正在尝试引用 PL/SQL 参数。

因为有多个表包含名为 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;

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;

相关内容

  • 没有找到相关文章

最新更新