Sql Orace:基于筛选器的默认列值

Sql Orace:基于筛选器的默认列值,sql,oracle,oracle11g,oracle10g,Sql,Oracle,Oracle11g,Oracle10g,您好,一位开发人员要求在表中添加一列,该列的默认值为“N”,但是如果该条目的id=3,则该列的默认值应为“Y”,我在oracle中是否可以实现这一点?11g方法 从oracle11g及更高版本中,您可以使用virtualcolumns一步完成此操作 测试用例 SQL> CREATE TABLE tab_default ( 2 ID NUMBER, 3 flag varchar2(1) GENERATED ALWAYS AS (decode(id, 3,

您好,一位开发人员要求在表中添加一列,该列的默认值为“N”,但是如果该条目的id=3,则该列的默认值应为“Y”,我在oracle中是否可以实现这一点?

11g方法

oracle11g
及更高版本中,您可以使用
virtualcolumns
一步完成此操作

测试用例

SQL> CREATE TABLE tab_default (
  2    ID          NUMBER,
  3    flag varchar2(1) GENERATED ALWAYS AS (decode(id, 3, 'Y', 'N')) VIRTUAL
  4  );

Table created.

SQL>
SQL> INSERT INTO tab_default (ID) VALUES (1);

1 row created.

SQL> INSERT INTO tab_default (ID) VALUES (3);

1 row created.

SQL> INSERT INTO tab_default (ID) VALUES (10);

1 row created.

SQL> SELECT * FROM tab_default;

        ID F
---------- -
         1 N
         3 Y
        10 N

SQL>
因此,
VIRTUAL
列声明中的
DECODE
函数为您处理需求

10g方法

您可以使用-

  • 默认值
  • 每当id=3时,插入触发器后的

  • 创建表,使
    默认值为'N'。仅当插入新行且值位于
    id
    column=3时,触发器才会触发,以便触发器将值更新为“Y”。否则,对于所有其他情况,默认值为“N”。

    向表中添加新列后,可以使用以下查询在列中插入值:

    update table_name set column_name = ( case when id = 3 then 'Y'  else 'N' end );    
    
    在插入新记录时,您可以使用以下方法:
    1) 在创建插入查询时决定列,您可以在创建查询时为该列添加逻辑。

    2) 在数据库中创建一个触发器,在向表中插入任何新行后,该触发器将更新列值。

    这是一个非常糟糕的数据库设计。它不尊重关系数据库的正常形式。
    我建议保持该表的原样,并在该表上创建一个新视图,其中包含一个额外的列,该列在以下情况下使用DECODE或CASE进行计算

    我同意评论人士提到的这不是一个好的数据库设计。也就是说,在现实生活中,对数据库设计做出妥协并不罕见

    我不确定是否需要虚拟专栏。OP要求提供一种违约的方式;虚拟列的工作方式不同于默认约束(例如,使用默认约束,我们可以在列中插入默认值以外的值。最佳方法可能是使用触发器设置“默认”值:

    无论您使用的是Oracle10g还是11g(您已经标记了两者),触发器都会起作用


    希望这能有所帮助。

    创建一个包含附加值列的新表:

    create table table1 as
    select u.*,
    case when id=3 then 'Y' ELSE 'N'
      END value  
    from table2 u
    

    我通常从应用程序端处理这些事情然后column='Y';----在DB中存储行----
    。如果DB中存在行,则只需在现有行的语句中使用大小写更新列即可。在insert过程中可能会为此添加一个触发器?
    虚拟列
    以及
    解码
    功能就是您所需要的一切。@Deepak Pawar:由于db完整性,应用程序将面临风险,因为您可能无法控制所有应用程序。此外,从维护的角度来看,许多应用程序可能需要更新。记录的ID是否真的为3?那么我们讨论的是一条记录。插入ID为3且值为“Y”的记录,并将“N”作为列的默认值。为什么要这样做使用后触发器而不是前触发器?因为后触发器至少可以确保事务向前进行。如果您依赖前触发器并基于此进行更改,则可能没有保证。不会有太大区别,但是,在这种情况下,我更喜欢后触发器。顺便说一句,我不太喜欢后触发器触发器,因为它们是一种效果的行为,因此是一种副作用。但是,在这种情况下,如果有人没有使用
    11g
    ,那么这是唯一的方法。这就是我编辑我的答案并将
    11g
    方法移到
    10g
    触发器方法之上的主要原因。不是每个应用程序都可以在一夜之间修复。这就是为什么我们需要这样做的原因在找到并实施永久解决方案之前,我会暂时采取一些变通办法。如果使用
    :new.mycolumn:=CASE:new.id当3时,那么'Y'ELSE'N'结束;
    而不是
    选择
    可以节省从PL/SQL引擎跳到SQL引擎再跳回来执行If测试的成本。而且我不相信您的引用在前面没有
    :new.
    的情况下,
    id
    的nce将在范围内。我也希望在这里对使用
    :old
    而不是
    :new
    发表评论。感谢您的评论,我认为您所提到的一切都是正确的。您也可以使用
    解码(:new.id,3,'Y',N'))
    而不是
    CASE
    等。请记住
    DECODE
    仅在SQL中有效,而不是在PL/SQL中有效。CASE在两者中都有效。
    create table table1 as
    select u.*,
    case when id=3 then 'Y' ELSE 'N'
      END value  
    from table2 u