Oracle 12c 数据默认值

Posted

技术标签:

【中文标题】Oracle 12c 数据默认值【英文标题】:Oracle 12c Data Default Value 【发布时间】:2020-11-13 10:49:14 【问题描述】:

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production

表:

CREATE TABLE t1 (
  c1 VARCHAR2(100 CHAR) DEFAULT 'SOME DATA' NOT NULL, 
  c2 DATE DEFAULT SYSDATE NOT NULL, 
  c3 NUMBER DEFAULT 10 NOT NULL);

选择:

BEGIN
  FOR c IN (SELECT * FROM user_tab_columns WHERE table_name = 'T1') LOOP
    DBMS_output.put_line('"' || c.data_default || '"');
  END LOOP;
END;

结果:

"'SOME DATA' "
"SYSDATE "
"10 "

为什么DATA DEFAULT 后面有空格?我需要将 Oracle 字典中的数据默认值与项目元数据中的数据默认值进行比较,但是这个空间破坏了比较。

编辑: @GordonLinoff 询问“多余的字符真的是空格吗?” 由于DATA_DEFAULT 列的LONG 数据类型,我发现只有一个测试:

DECLARE
  l_ret   VARCHAR2(32000);
  l_dump  VARCHAR2(32000);
BEGIN
  FOR c IN (SELECT * FROM user_tab_columns WHERE table_name = 'T1') LOOP
    DBMS_output.put_line('"' || c.data_default || '"');
    l_ret := c.data_default;
    SELECT dump(l_ret) 
      INTO l_dump
      FROM dual;
    DBMS_output.put_line(l_dump);
  END LOOP;
END;

结果:

"10 "
Typ=1 Len=3: 49,48,32
"SYSDATE "
Typ=1 Len=8: 83,89,83,68,65,84,69,32
"'SOME DATA' "
Typ=1 Len=12: 39,83,79,77,69,32,68,65,84,65,39,32

所以,它是一个空格 (32)。

【问题讨论】:

。 .我怀疑这是默认值存储为long 的产物。额外的字符真的是一个空格还是看起来像一个? 您的查询没有查看表中的值;它正在查看数据字典中表的定义。那么只要甲骨文处理得当,有什么区别呢? @Belayer - OP 非常清楚地解释了(在我看来)他是如何使用它的。他正在将“Oracle 知道”(即数据字典)与他的规范进行比较,以确保 create table 语句按照规范正确执行。这应该在表格中填充任何实际数据之前预先完成。你现在明白这有什么不同了吗?您不想等到填充数据后,才然后查看默认值是否正常。 【参考方案1】:

有趣。

一个简单的测试表明,仅当您为其定义默认值的列声明为 NOT NULL 时,才会添加额外的空间。 (因此,与@GordonLinoff 推测的相反,这不是将默认值存储为 LONG 的产物。)

甲骨文为什么要这样做……谁知道呢。

无论如何,当您将字典中的默认值与您的规范(项目元数据)进行比较时,最简单的解决方案似乎是有条件地在另一个术语的末尾添加一个尾随空格在比较中。 (以列是否为 NOT NULL 为条件。)

或者,如果您确实需要直接操作声称的默认值,您还可以从 USER_TAB_COLUMNS 检索 DEFAULT_LENGTH 值,这样您就可以轻松地仅删除尾随空格(当列不可为空时),同时保留任何尾随空格这可能是实际所需默认值的一部分。 (例如:非 NULL 文本列的默认值正好是一个空格;DEFAULT_VALUE 报告为两个空格,您只想修剪第二个空格,而不是第一个。)

【讨论】:

【参考方案2】:

你可以trim()那个:

BEGIN
  FOR c IN (SELECT * FROM user_tab_columns WHERE table_name = 'T1') LOOP
    DBMS_output.put_line('"' || trim(c.data_default) || '"');
  END LOOP;
END;
/

【讨论】:

trim 不是一个好的解决方案;默认值可能包含前导或尾随空格,应保留 - 但它们将与不需要的最后一个空格一起被修剪掉。

以上是关于Oracle 12c 数据默认值的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 12C 新特性之扩展数据类型(extended data type)

ORACLE12C PDB创建默认表空间和用户语句

Oracle12c:安装后新建用户及其默认表空间,并创建表测试

oracle数据库中给字段加默认值的问题

如何给Oracle的数据添加默认值

oracle数据库的一个表中,怎么设置字段的默认值