SQL Select 语句 - 字段不存在时的默认字段值
Posted
技术标签:
【中文标题】SQL Select 语句 - 字段不存在时的默认字段值【英文标题】:SQL Select statement - default field value when field doesn't exist 【发布时间】:2015-11-24 16:19:02 【问题描述】:我想知道是否有办法在查询字段不存在的情况下为 select 语句显示一些默认值。
例如,
SELECT t.name, t.type, t.price, t.brand FROM some_table t;
如果 some_table 中不存在“品牌”字段,我希望此语句将“品牌”显示为“不可用”。
最终我想从那个 select 语句创建一个视图。 我只是好奇在 PL/SQL 中是否有办法做到这一点。
编辑: 为避免混淆,我希望在表中不存在“品牌”列时编译并运行该语句。
【问题讨论】:
列名必须在编译时知道。一种解决方法是使用 dynamic-sql 只是为了确保您正确理解@lad2025 的评论,您想要一个默认值,当该值为null 时,或者您想要查询字段name
, type
、price
、brand
来自无法在运行时确定的表?
@Grentley 我很好奇,如果不知道列是否存在,如何知道结构?它应该要么知道它存在,要么知道它不存在。
请参阅:blog.sqlauthority.com/2013/07/01/…
@CM2K 用于 SQL Server。在 Oracle 中查询的数据字典表完全不同。还有 T-SQL =/= PL/SQL。
【参考方案1】:
你可以用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';
If 1 then EXIST else NOT 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;
但我看不到正确的使用方法。
【讨论】:
当表没有列brand
时你会得到什么?顺便说一句,Oracle 有NVL
@lad2025 对不起,现在我明白了问题,删除答案?
等待 OP 评论。他的问题可能模棱两可
我得到一个编译错误。我希望此语句在 t.brand 列不存在时起作用。
是表结构在运行时未知的问题:即它可能有4个数据字段,也可能有5个数据字段?或者“品牌”可能没有字段中的数据(即品牌在某些记录上为 NULL)的问题?你的陈述似乎是双方的——你能澄清一下吗??【参考方案2】:
除非您进行一些非常繁重且笨重的元数据收集,您只需查询主表以获取数据,然后将其全部转换为行,否则您无法查询不存在的列,因为编译器将启动挂了他的东西,却找不到专栏。
您可以通过使用动态 sql 来绕过它,但是您只会遇到运行时错误,因为您仍在查询不存在的列。
这意味着如果该列不在该表中,您的动态 SQL 将不得不排除该列,此时您最好从静态 SQL 中删除该列。动态 SQL 真正更好的唯一一点是,如果您必须查询 30 多个表并且您知道自己在做什么。
那么基本上,为什么需要查询不存在的列?在你的情况下,如果它只是为了能够保留一个过时的视图,你最好在需要更新时简单地维护你的视图。
【讨论】:
我认为这个想法是作为动态 sql 的一部分,您将检查列是否存在,然后将其添加到选择列表中,或使用“不可用”文字用合适的别名代替它的值。 是的,我的回答具有误导性,我改写了它应该更好。【参考方案3】:我刚刚看到了上面的问题。看起来很奇怪的设计或要求。我发布的代码 sn-p 可能足以解决您的问题,但理想情况下不应该是这样的。
--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;
【讨论】:
【参考方案4】:SELECT t.name, t.type, t.price, NVL(t.brand,"Not available") FROM some_table t;
【讨论】:
以上是关于SQL Select 语句 - 字段不存在时的默认字段值的主要内容,如果未能解决你的问题,请参考以下文章