• http://www.jiahegou.com
  • ITPUB论坛-中国最专业的IT技术社区

     找回密码
     注册
    查看: 638|回复: 5

    [每日一题] PL/SQL Challenge 每日一题:2018-1-4 TO_TIMESTAMP_TZ函数

    [复制链接]
    论坛徽章:
    486
    秀才
日期:2018-07-21 10:33:01秀才
日期:2018-07-21 10:03:12秀才
日期:2018-07-21 10:03:12秀才
日期:2018-07-21 10:03:12状元
日期:2018-07-21 10:04:09举人
日期:2018-07-21 10:04:09秀才
日期:2018-07-21 14:10:21秀才
日期:2018-07-21 14:10:21秀才
日期:2018-07-21 14:10:21秀才
日期:2018-07-21 14:10:21
    跳转到指定楼层
    1#
    发表于 2018-1-9 06:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

    每两周的优胜者可获得itpub奖励的技术图书一本。

    以往旧题索引:
    http://www-itpub-net.bwp888.com/forum.php?m ... eid&typeid=1808

    原始出处:
    http://www.plsqlchallenge.com.bwp888.com/

    作者: Kim Berg Hansen

    运行环境:SQLPLUS, SERVEROUTPUT已打开
    注:本题给出答案时候要求给予简要说明才能得到奖品

    我有些朋友住在不同的时区:

    create table qz_friends (
       friend   varchar2(10)
    , tzname   varchar2(64)
    )
    /

    insert into qz_friends values ('Cecilia' , 'America/Chicago')
    /
    insert into qz_friends values ('Lucille' , 'Europe/London'  )
    /
    insert into qz_friends values ('Patricia', 'Australia/Perth')
    /
    commit
    /

    在应用中,所有的会话都使用UTC时区:

    alter session set time_zone='UTC'
    /

    我住在丹麦,时区是 Europe/Copenhagen, 我想要知道在什么时间(我的当地时间)需要给我的每个朋友发送“新年快乐”的短信,使得他们会在当地时间的午夜收到这条短信。

    我写了个未完成的查询来获取这些时间:

    select friend
         , to_char(
              ##REPLACE##
            , 'YYYY-MM-DD HH24:MI:SS TZR'
           ) as time_for_sms
      from qz_friends
    order by time_for_sms
    /

    哪些选项包含的表达式可用来取代##REPLACE##使得查询返回这个输出:

    FRIEND     TIME_FOR_SMS
    ---------- ----------------------------------------------------
    Patricia   2018-07-21 17:00:00 EUROPE/COPENHAGEN
    Lucille    2018-07-21 01:00:00 EUROPE/COPENHAGEN
    Cecilia    2018-07-21 07:00:00 EUROPE/COPENHAGEN

    (A)
      TO_TIMESTAMP(
                 '2018-07-21 00:00:00 ' || tzname
               , 'YYYY-MM-DD HH24:MI:SS TZR'
              ) AT TIME ZONE 'Europe/Copenhagen'

    (B)
    TO_TIMESTAMP_TZ(
                 '2018-07-21 00:00:00 ' || tzname
               , 'YYYY-MM-DD HH24:MI:SS TZR'
              ) AT TIME ZONE 'Europe/Copenhagen'

    (C)
      FROM_TZ(
                 TO_TIMESTAMP(
                    '2018-07-21 00:00:00'
                  , 'YYYY-MM-DD HH24:MI:SS'
                 )
               , tzname
              ) AT TIME ZONE 'Europe/Copenhagen'

    (D)
           FROM_TZ(
                 TIMESTAMP '2018-07-21 00:00:00'
               , tzname
              ) AT TIME ZONE 'Europe/Copenhagen'

    (E)
             ( TIMESTAMP '2018-07-21 00:00:00'
                AT TIME ZONE 'Europe/Copenhagen' )
              AT TIME ZONE tzname

    (F)
             ( TIMESTAMP '2018-07-21 00:00:00'
                AT TIME ZONE tzname )
              AT TIME ZONE 'Europe/Copenhagen'

    论坛徽章:
    20
    2012新春纪念徽章
日期:2018-07-21 11:58:44秀才
日期:2018-07-21 09:55:08秀才
日期:2018-07-21 09:55:08秀才
日期:2018-07-21 10:21:13秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 15:04:10秀才
日期:2018-07-21 15:10:43秀才
日期:2018-07-21 09:55:08
    2#
    发表于 2018-1-9 08:20 | 只看该作者
    正确答案:BCDF
    A:会报日期格式无法识别的错误,TO_TIMESTAMP函数不能转换为时区
    B:正确,TO_TIMESTAMP_TZ函数可以转换为时区
    C:正确,Oracle 中的from_tz函数,可以将一个timstamp和timzone拼成一个timestamp with timezone(文档:FROM_TZ converts a timestamp value and a time zone to a TIMESTAMP WITH TIME ZONE value. time_zone_value is a character string in the format 'TZH:TZM' or a character expression that returns a string in TZR with optional TZD format.)
    D:正确
    E:错误,将哥本哈根的时间转换为了其他地区的时间。
    F:正确,将其他地区的时间转换为哥本哈根的时间。
    认证徽章
    论坛徽章:
    0
    3#
    发表于 2018-1-9 16:10 | 只看该作者
    BCD吧
    论坛徽章:
    486
    秀才
日期:2018-07-21 10:33:01秀才
日期:2018-07-21 10:03:12秀才
日期:2018-07-21 10:03:12秀才
日期:2018-07-21 10:03:12状元
日期:2018-07-21 10:04:09举人
日期:2018-07-21 10:04:09秀才
日期:2018-07-21 14:10:21秀才
日期:2018-07-21 14:10:21秀才
日期:2018-07-21 14:10:21秀才
日期:2018-07-21 14:10:21
    4#
     楼主| 发表于 2018-1-10 05:19 | 只看该作者
    答案BCD,本期无人得奖。3楼请注意在自己答案加上简要说明。

    A: TO_TIMESTAMP 函数返回的数据类型是TIMESTAMP, 而非 TIMESTAMP WITH TIME ZONE。因此我们不能用TZR,这个选项会报错:
    ORA-01821: date format not recognized.         

    B: 我们应该用的是TO_TIMESTAMP_TZ,它接受TZR格式,返回数据类型TIMESTAMP WITH TIME ZONE. 然后我们得到了所要的结果。

    C: 前一选项的替代办法是用TO_TIMESTAMP来得到不带时区的TIMESTAMP信息,然后用FROM_TZ将TIMESTAMP转换成指定时区的TIMESTAMP WITH TIME ZONE

    D: 我们可以不用前一选项的TO_TIMESTAMP,而是使用一个TIMESTAMP字面常量来达到同样目的。
    E: 此处我们创建了一个TIMESTAMP字面常量,它被隐式转换成会话所在时区UTC的 TIMESTAMP WITH TIME ZONE。然后我们问这个时间点在Europe/Copenhagen 时区是什么时间,然后同样时间点在TZNAME的时区又是什么时间。所以我们得到的不是想要的输出,而是UTC午夜的时候在我的朋友的时区是什么时间:

    FRIEND     TIME_FOR_SMS
    ---------- ----------------------------------------------------
    Cecilia    2018-07-21 18:00:00 AMERICA/CHICAGO
    Lucille    2018-07-21 00:00:00 EUROPE/LONDON
    Patricia   2018-07-21 08:00:00 AUSTRALIA/PERTH

    F: 我们创建的同样的TIMESTAMP字面常量再次被隐式转换成UTC午夜的时间点了。然后我们问这个时间点在TZNAME的时区是什么时间,然后同样时间点在Europe/Copenhagen时区又是什么时间。所以输出了UTC午夜在哥本哈根的时间:

    FRIEND     TIME_FOR_SMS
    ---------- ----------------------------------------------------
    Cecilia    2018-07-21 01:00:00 EUROPE/COPENHAGEN
    Patricia   2018-07-21 01:00:00 EUROPE/COPENHAGEN
    Lucille    2018-07-21 01:00:00 EUROPE/COPENHAGEN

    论坛徽章:
    20
    2012新春纪念徽章
日期:2018-07-21 11:58:44秀才
日期:2018-07-21 09:55:08秀才
日期:2018-07-21 09:55:08秀才
日期:2018-07-21 10:21:13秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 15:04:10秀才
日期:2018-07-21 15:10:43秀才
日期:2018-07-21 09:55:08
    5#
    发表于 2018-1-10 08:10 | 只看该作者
    newkid 发表于 2018-1-10 05:19
    答案BCD,本期无人得奖。3楼请注意在自己答案加上简要说明。

    A: TO_TIMESTAMP 函数返回的数据类型是TIME ...

    C:\Users\JohnLee\Desktop\题.png,我这里执行出来结果是正确的。
    论坛徽章:
    20
    2012新春纪念徽章
日期:2018-07-21 11:58:44秀才
日期:2018-07-21 09:55:08秀才
日期:2018-07-21 09:55:08秀才
日期:2018-07-21 10:21:13秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 10:30:00秀才
日期:2018-07-21 15:04:10秀才
日期:2018-07-21 15:10:43秀才
日期:2018-07-21 09:55:08
    6#
    发表于 2018-1-10 08:18 | 只看该作者
    本帖最后由 liwenrongdba 于 2018-1-10 08:20 编辑
    newkid 发表于 2018-1-10 05:19
    答案BCD,本期无人得奖。3楼请注意在自己答案加上简要说明。

    A: TO_TIMESTAMP 函数返回的数据类型是TIME ...

    F选项我这里执行出来是正确的,难道是我设置了nls_date_format?
    SQL> alter session set time_zone='UTC';
    Session altered

    SQL>
    SQL> select friend
      2       , to_char(
      3            ( TIMESTAMP '2018-07-21 00:00:00'
      4              AT TIME ZONE tzname )
      5            AT TIME ZONE 'Europe/Copenhagen'
      6          , 'YYYY-MM-DD HH24:MI:SS TZR'
      7         ) as time_for_sms
      8    from qz_friends
      9  order by time_for_sms
    10  ;
    FRIEND TIME_FOR_SMS
    ---------- ----------------------------------------------------
    Patricia 2018-07-21 17:00:00 EUROPE/COPENHAGEN
    Lucille 2018-07-21 01:00:00 EUROPE/COPENHAGEN
    Cecilia 2018-07-21 07:00:00 EUROPE/COPENHAGEN

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    -刘桥村委会论坛,刘桥村委会社区 - www-bbs-stb.bwp888.com
    DTCC2018购票6.8折优惠进行时

    中国数据库技术大会是国内数据库及大数据领域规模最大、最受欢迎的技术交流盛会。 2018年5月10-12日,第九届中国数据库技术大会将如约而至。本届大会以“数领先机•智赢未来”为主题,设定2大主会场及20个技术专场,邀请来自国内外互联网、金融、教育等行业百余位技术专家,共同探讨Oracle、MySQL、NoSQL、大数据等领域的前瞻性热点话题与技术。
    ----------------------------------------
    优惠时间:2018-07-21前

    报名链接>>
    蚌埠市论坛 宁江区论坛 木垒县论坛 贺兰县论坛 阿尔山市论坛
    惠城区论坛 拜城县论坛 江城县论坛 弹子石论坛 大浪咀论坛
    电子杂志 虎吧 老博客 读书频道 积分竞拍 文本模式 帮助
      IT博客
      ChinaUnix | ChinaUnix博客 | ChinaUnix论坛 | SAP ERP系统
    CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
    京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
      
    快速回复 返回顶部 返回列表
    澎湖列岛论坛 博爱县论坛 松滋市论坛 周村区论坛 友谊县论坛
    福石论坛 布泉乡论坛 广水市论坛 华强街道论坛 凉城县论坛