SQL Select语句-字段不存在时的默认字段值

SQL Select语句-字段不存在时的默认字段值,sql,oracle,plsql,Sql,Oracle,Plsql,我想知道是否有一种方法可以在查询字段不存在的情况下为select语句显示一些默认值 比如说, SELECT t.name, t.type, t.price, t.brand FROM some_table t; 如果“品牌”字段在some_表中不存在,我希望此语句将“品牌”显示为“不可用” 最后,我想从select语句创建一个视图。 我只是好奇在PL/SQL中是否有这样做的方法 编辑: 为了避免混淆,我希望在表中不存在“brand”列时编译并使用该语句。您可以使用COALESCE,通过nota

我想知道是否有一种方法可以在查询字段不存在的情况下为select语句显示一些默认值

比如说,

SELECT t.name, t.type, t.price, t.brand FROM some_table t;
如果“品牌”字段在some_表中不存在,我希望此语句将“品牌”显示为“不可用”

最后,我想从select语句创建一个视图。 我只是好奇在PL/SQL中是否有这样做的方法

编辑: 为了避免混淆,我希望在表中不存在“brand”列时编译并使用该语句。

您可以使用COALESCE,通过notavailable更改null

COALESCE是sql标准,但我不知道Oracle是否有它

编辑:

我认为您必须首先检查表中是否存在字段,例如:

Select count(*) into v_column_exists
from user_tab_cols
where column_name = 'ADD_TMS'
  and table_name = 'EMP';
如果1,则存在,否则不存在,请根据结果创建视图

1:

2:


但是我看不出正确的方法来使用它。

除非你进行一些非常繁重和笨拙的元数据收集,你只需查询主表来获取数据,然后将其全部解压到行中,否则你无法查询不存在的列,因为编译器将开始连接他的内容,并且找不到该列

SELECT t.name, t.type, t.price, NVL(t.brand,"Not available") FROM some_table t;
您可以通过使用动态sql来绕过这一点,但由于您仍在查询不存在的列,因此只会出现运行时错误

这意味着,如果该列不在该表中,动态SQL将不得不排除该列,此时最好从静态SQL中删除该列。动态SQL真正更好的唯一一点是,如果您必须查询30多个表,并且您知道自己在做什么


那么基本上,为什么需要查询不存在的列呢?在您的情况下,如果只是为了保留过时的视图,那么最好在视图需要更新时简单地维护视图。

我刚刚看到了上面的问题。它的设计或要求似乎很奇怪。我发布的代码片段可能足以解决您的问题,但理想情况下,这不应该是这样的

--So i get chance to look into the question asked simple way to get a workaround for your problem is to fetch out the columns list from table
var p_lst refcursor;
SET serveroutput ON;
DECLARE
  lv_sql LONG;
  lv_tab_name VARCHAR2(100);
  lv_col_chk  VARCHAR2(1000 CHAR);
BEGIN
  FOR I IN
  (SELECT * FROM ALL_TAB_COLUMNS WHERE OWNER = 'AVROY' AND TABLE_NAME = 'EMP'
  )
  LOOP
    lv_tab_name:=I.TABLE_NAME;
    lv_sql     :=lv_sql||','||i.column_name;
  END LOOP;
  lv_sql:='SELECT '||SUBSTR(lv_sql,2,LENGTH(lv_sql));
  dbms_output.put_line(lv_sql);
  lv_col_chk:=INSTR(UPPER(lv_sql),'BRAND',1);
  dbms_output.put_line(lv_col_chk);
  IF lv_col_chk = 0 THEN
    lv_sql     :=SUBSTR(lv_sql,1,LENGTH(lv_sql))||', ''Not_available'' as Brand_col  FROM '||lv_tab_name;
    dbms_output.put_line(LV_SQL);
  ELSE
    lv_sql:=SUBSTR(lv_sql,1,LENGTH(lv_sql))||' FROM '||lv_tab_name;
    dbms_output.put_line(LV_SQL);
  END IF;
  OPEN :p_lst FOR lv_sql;
END;
PRINT p_lst;

列名必须在编译时已知。一种解决方法是使用dynamic sqlJust以确保您正确理解@lad2025的注释,您是希望在值为null时使用默认值,还是希望从运行时无法确定的表中查询字段名称、类型、价格、品牌?@Grentley我很好奇,在不知道是否存在列的情况下,如何知道结构?它应该知道它存在,或者知道它不存在。请参阅:@CM2K,这是用于SQL Server的。在Oracle中查询的数据字典表是完全不同的。另外,T-SQL=/=PL/SQL。当表没有列品牌时,您将得到什么?甲骨文已通过NVLway@lad2025对不起,现在我明白了问题,请删除答案?等待评论。他的问题可能模棱两可,因为我有一个编译错误。当t.brand列不存在时,我希望此语句起作用。表结构在运行时是未知的问题:即它可能有4个数据字段,或者可能有5个数据字段?或者是brand可能在某些记录上的brand为空字段中没有数据的问题??您的陈述似乎有两面性-您能澄清一下吗?我认为,作为动态sql的一部分,您应该检查列的存在,然后将其添加到选择列表中,或者在其位置使用不可用的文本值,并使用合适的别名。是的,我的回答有误导性,我重新措辞,这样应该更好。
SELECT t.name, t.type, t.price, 'not available' AS brand FROM some_table t;
SELECT t.name, t.type, t.price, NVL(t.brand,"Not available") FROM some_table t;
--So i get chance to look into the question asked simple way to get a workaround for your problem is to fetch out the columns list from table
var p_lst refcursor;
SET serveroutput ON;
DECLARE
  lv_sql LONG;
  lv_tab_name VARCHAR2(100);
  lv_col_chk  VARCHAR2(1000 CHAR);
BEGIN
  FOR I IN
  (SELECT * FROM ALL_TAB_COLUMNS WHERE OWNER = 'AVROY' AND TABLE_NAME = 'EMP'
  )
  LOOP
    lv_tab_name:=I.TABLE_NAME;
    lv_sql     :=lv_sql||','||i.column_name;
  END LOOP;
  lv_sql:='SELECT '||SUBSTR(lv_sql,2,LENGTH(lv_sql));
  dbms_output.put_line(lv_sql);
  lv_col_chk:=INSTR(UPPER(lv_sql),'BRAND',1);
  dbms_output.put_line(lv_col_chk);
  IF lv_col_chk = 0 THEN
    lv_sql     :=SUBSTR(lv_sql,1,LENGTH(lv_sql))||', ''Not_available'' as Brand_col  FROM '||lv_tab_name;
    dbms_output.put_line(LV_SQL);
  ELSE
    lv_sql:=SUBSTR(lv_sql,1,LENGTH(lv_sql))||' FROM '||lv_tab_name;
    dbms_output.put_line(LV_SQL);
  END IF;
  OPEN :p_lst FOR lv_sql;
END;
PRINT p_lst;