如何避免Oracle中的无效标识符

时间:2019-01-28 08:59:43

标签: sql oracle plsql

我需要创建一个视图,但出现此错误“无效标识符”。问题是我尝试访问一个不存在的列名,但我需要在我的视图中使用(如果该列不存在,则需要输入null)。这是我的代码sql:

select .......
case 
when
   when exists (select 1  from user_tab_columns where table_name = 'Student' and COLUMN_NAME = 'email') then nvl(SUBSTR(student.email, 0, 100),'') else ''
end as STUDENT_EMAIL,

这引发了“ invalid identifier”。我需要创建该视图并创建“电子邮件”字段,如果存在,我必须插入正确的字段,否则我将字段值设置为null;

2 个答案:

答案 0 :(得分:5)

使用动态SQL并尝试编译视图,如果有错误,请改用NULL

Oracle设置

CREATE TABLE students ( id, name )
AS SELECT 1, 'Alice' FROM DUAL;

创建视图

DECLARE
  invalid_identifier EXCEPTION;
  PRAGMA EXCEPTION_INIT( invalid_identifier, -904);
BEGIN
  EXECUTE IMMEDIATE 'CREATE VIEW student_view AS SELECT id, name, SUBSTR( email, 1, 100 ) AS STUDENT_EMAIL FROM students';
EXCEPTION
  WHEN invalid_identifier THEN
    EXECUTE IMMEDIATE 'CREATE VIEW student_view AS SELECT id, name, CAST( null AS VARCHAR2(100) ) AS STUDENT_EMAIL FROM students';
END;
/

结果

SELECT * FROM student_view;
ID | NAME  | STUDENT_EMAIL
-: | :---- | :------------
 1 | Alice | null         

db <>提琴here

答案 1 :(得分:0)

有一种巧妙但巧妙的方法,无需使用动态SQL。

您可以对子查询使用范围规则来分配email(如果存在)。挑战在于您需要提供默认值,并且需要主键:

select . . .,  -- all columns from `s` *except* for email
       (select email  -- no qualification
        from students s2
        where s2.id = s.id
       ) as email 
from student s cross join
     (select '' as email from dual
     ) e;

如果emailstudents中,则select email选择该值。如果不是email,则从e中选择它。