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

时间:2015-11-24 16:19:02

标签: sql oracle plsql

我想知道是否有办法显示select语句的某些默认值,其中查询字段不存在。

例如,

SELECT t.name, t.type, t.price, t.brand FROM some_table t;

如果some_table中不存在“品牌”字段,我希望此声明将“品牌”显示为“不可用”。

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

编辑: 为了避免混淆,我希望语句在表中不存在“品牌”列时进行编译和工作。

4 个答案:

答案 0 :(得分:3)

您可以使用COALESCE,将null更改为not available

SELECT t.name, t.type, t.price, COALESCE(t.brand,'not available') AS brand FROM some_table t;

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

编辑:

我认为你必须首先检查表中存在的字段,如:

Select count(*) into v_column_exists
from user_tab_cols
where column_name = 'ADD_TMS'
  and table_name = 'EMP';

如果为1,那么在根据结果创建视图后,EXIST否则不存在。

1:

SELECT t.name, t.type, t.price, t.brand FROM some_table t;

2:

SELECT t.name, t.type, t.price, 'not available' AS brand FROM some_table t;

但是我无法在视野中看到正确的方法。

答案 1 :(得分:2)

除非你进行一些非常沉重和笨重的元数据收集,你只需查询主表来获取数据然后将它们全部转换为行,就不能查询不存在的列,因为编译器将启动连接他的东西,不会找到专栏。

您可以通过使用动态sql来绕过它,但之后您只会遇到运行时错误,因为您仍然在查询不存在的列。

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

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

答案 2 :(得分:1)

SELECT t.name, t.type, t.price, NVL(t.brand,"Not available") FROM some_table t;

答案 3 :(得分:1)

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

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