【问题标题】:How to change default date,timestamp dataype for columns in oracle如何更改oracle中列的默认日期、时间戳数据类型
【发布时间】:2015-03-26 05:07:33
【问题描述】:

我在 Oracle 中创建了一个表,其中有 KPI_START_DATE 列,这是一个 Date 数据类型,KPI_START_TIME 是一个 TIMESTAMP 数据类型。 现在我想修改这个日期数据类型为

KPI_START_DATEdd/mm/yyyy

KPI_START_TIMEHH:MI:SS

因此,用户应始终以正确的格式在此列中输入日期和时间。

我尝试了下面的查询,但它给出了错误:

Alter table KPI_DEFINITION MODIFY(to_char(KPI_START_DATE,'dd/mm/yyyy') )

【问题讨论】:

  • Oracle 的众多优点之一是,它很早就认识到不应将日期和时间格式与数据本身混淆。它通过不以用户格式存储任何日期或时间,而是使用数学值来“解决”该问题。实际上,它显示的值更精确,但那是另一回事。重要的是要知道:Oracle 仅使用格式进行显示,而不使用存储。它不存储日期或时间的格式。 - 如果您考虑将时间和日期存储为 CHAR 或 VARCHAR2:请不要考虑!

标签: oracle date timestamp sqldatatypes


【解决方案1】:

DISPLAYINGSTORINGDATE 方面不同

当人们说 Oracle 没有以他们想要的格式存储日期时,真正发生的是 Oracle 没有以他们期望或想要的字符串格式显示日期。

When a data element of type DATE is selected, it must be converted from its internal, binary format, to a string of characters for human consumption.数据从一种类型到另一种类型的转换称为“转换”、“类型转换”或“强制转换”。在 Oracle 中,日期和字符串之间的转换由 NLS_DATE_FORMAT 模型控制。 NLS_DATE_FORMAT 可以设置在几个不同的位置,每个位置都有自己的影响范围。

我可以继续我关于 DATE 数据类型的演讲,但我很高兴有人已经对此进行了很好的阐述。请阅读此https://edstevensdba.wordpress.com/2011/04/07/nls_date_format/

【讨论】:

    【解决方案2】:

    DATETIMESTAMP 列没有任何固有的可读格式。这些值存储在 Oracle 自己的内部表示中,与人类可读的日期或时间没有相似之处。在检索或显示值时,您可以使用to_char() 将其转换为您想要的任何格式。

    DATE 和 TIMESTAMP 都具有日期和时间组件(使用 DATE 精确到秒,使用 TIMESTAMP 精确到小数秒;加上扩展数据类型的时区信息),您不应尝试将它们分别存储为两列。拥有一栏,随时提取您需要的信息;要从单个列中获取信息,但可以拆分为两个字段:

    select to_char(KPI_START, 'dd/mm/yyyy') as KPI_START_DATE,
      to_char(KPI_START, 'hh24:mi:ss') as KPI_START_TIME
    

    但您通常还是希望两者在一起:

    select to_char(KPI_START, 'dd/mm/yyyy hh24:mi:ss')
    

    还要注意 'hh24' 格式模型获取 24 小时制时间;否则你不会看到凌晨 3 点和下午 3 点之间有任何区别

    您可以在任一类型的列中存储一个值,并将时间设置为午夜,但它仍然有一个时间组件 - 它只是午夜。您不能在任何一种类型的列中仅使用时间组件存储值 - 它也必须具有日期。您可以将其设为名义日期并忽略它,但我从未见过这样做的正当理由 - 您在两列中浪费存储空间,并使搜索和比较值变得更加困难。如果您不指定一个日期(当月的第一天),Oracle 甚至会提供一个默认日期。但该值始终同时包含日期和时间部分:

    create table KPI_DEFINITION (KPI_START date);
    insert into KPI_DEFINITION (KPI_START)
      values (to_date('27/01/2015', 'DD/MM/YYYY'));
    insert into KPI_DEFINITION (KPI_START)
      values (to_date('12:41:57', 'HH24:MI:SS'));
    select to_char(KPI_START, 'YYYY-MM-DD HH24:MI:SS') from KPI_DEFINITION;
    
    TO_CHAR(KPI_START,'YYYY-MM-DDHH24:MI:SS')
    -----------------------------------------
    2015-01-27 00:00:00                       
    2015-01-01 12:41:57                       
    

    您的用户应该插入一个日期和时间都为一个的值:

    insert into KPI_DEFINITION (KPI_START)
      values (to_date('27/01/2015 12:41:57', 'DD/MM/YYYY HH24:MI:SS'));
    select to_char(KPI_START, 'YYYY-MM-DD HH24:MI:SS') from KPI_DEFINITION;
    
    TO_CHAR(KPI_START,'YYYY-MM-DDHH24:MI:SS')
    -----------------------------------------
    2015-01-27 12:41:57  
    

    您也可以使用date or timestamp literals,如果使用to_date(),您应该始终指定完整格式 - 不要依赖 NLS 设置,因为其他用户可能会有所不同。

    【讨论】:

    • 在 oracle 的日期数据类型中,它存储日期和时间。我不想要那个。我只希望在日期数据类型中它应该输入日期,而在时间戳中它应该输入时间。例如:创建表 t1 ( flight_date date, flight_time as (to_char(flight_date,'HH24:SS:MI')), flight_day as (to_char(flight_date,'dd/mm/yyyy')) );
    • 不能只在日期数据类型中插入日期,在时间戳中插入时间吗? oracle 中是否有任何对此有用的数据类型?当用户在此列中输入值时,这一点很重要......我不希望他们插入任何东西。
    • @ajay - 您可以存储一个时间设置为午夜的日期;这是最接近没有时间的日期,但重要的是要意识到它仍然有时间成分。并且你不能有一个 DATE 或一个带有 just 时间组件的 TIMESTAMP,它必须有一个有效的日期。您可以使用名义日期并稍后忽略它,或者使用我猜的 INTERVAL。但是无论如何,您都需要一个非常好的理由来分别存储这两个部分,而且我认为我从未见过。这使比较变得更加困难,我认为这样做没有任何好处。您的用户应该将完整的日期时间插入一列。
    【解决方案3】:

    您应该了解 datatypeformat 之间的区别。 DATE 是一种数据类型。 TIMESTAMP 是一种数据类型。它们都没有格式,它们只是数字。

    将字符数据类型转换为日期数据类型或从日期数据类型转换时,应应用格式。这是实际转换的属性,仅此而已。

    看看这个:

    SQL> create table tmp$date(d date);
    
    Table created
    
    SQL> insert into tmp$date values (DATE '2010-11-01');
    
    1 row inserted
    
    SQL> insert into tmp$date values (DATE '2014-12-28');
    
    1 row inserted
    
    SQL> select d, dump(d) from tmp$date;
    
    D           DUMP(D)
    ----------- ---------------------------------
    01.11.2010  Typ=12 Len=7: 120,110,11,1,1,1,1
    28.12.2014  Typ=12 Len=7: 120,114,12,28,1,1,1
    

    这里没有任何“格式”。

    【讨论】:

    • 在 oracle 的日期数据类型中,它存储日期和时间。我不想要那个。我只希望在日期数据类型中它应该输入日期,而在时间戳中它应该输入时间。例如:创建表 t1 ( flight_date date, flight_time as (to_char(flight_date,'HH24:SS:MI')), flight_day as (to_char(flight_date,'dd/mm/yyyy')) );
    • 不能只在日期数据类型中插入日期,在时间戳中插入时间吗? oracle 中是否有任何对此有用的数据类型?当用户在此列中输入值时,这一点很重要......我不希望他们插入任何东西。
    • 一切皆有可能。但是,如果您希望将一个数字的整数部分存储到一个变量中,而将该数字的小数部分存储到另一个变量中,您不应该怀疑它是否看起来缺乏支持、不舒服和荒谬。
    • 谢谢你 :) 你是对的,在 oracle 中不可能设置这样的格式 :)
    猜你喜欢
    • 2011-11-01
    • 2020-09-28
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多