zoukankan      html  css  js  c++  java
  • TIMESTAMPN(N) WITH LOCAL TIMEZONE数据类型转换

    --TYPE#=231为TIMESTAMP(N) WITH LOCAL TIME ZONE,181为TIMESTAMP(N) WITH TIME ZONE
    select u.name || '.' || o.name || '.' || c.name TSLTZcolumn
    from sys.obj$ o, sys.col$ c, sys.user$ u
    where c.type#=231 and o.obj#=c.obj# and u.user#=o.owner#;
    ------------------------------------
    --某时区和 UTC 之间的差值
    SELECT TZ_OFFSET('US/Eastern') FROM DUAL;
    SELECT TZ_OFFSET(DBTIMEZONE) FROM DUAL;
    SELECT TZ_OFFSET(SESSIONTIMEZONE) FROM DUAL;
    SELECT TZ_OFFSET('-11:11') FROM DUAL
    --数据库时区
    SELECT DBTIMEZONE FROM DUAL;
    --会话时区
    SELECT SESSIONTIMEZONE FROM DUAL;
    ------------------------------------
    --TIMESTAMP(N) WITH TIME ZONE TIMESTAMP(N) WITH LOCAL TIME ZONE 存储格式及引擎 sql引擎
    --TO_TIMESTAMP_TZ函数 时的12和24进度 最小精度为纳秒
    --AM/PM都可以转换得到下午,此时HH12为12进度(由上午、下午和格式中的AM/PM限制)且此时可以忽略TZR时区格式而只指定AM/PM
    --TO_TIMESTAMP_TZ得到的数据类型用TO_CHAR转换时,12和24进度都可以指定AM/PM格式,反之只有12进度可以指定
    --不含时区 12进度 得到默认时区 必须写上午和下午否则只能得到上午的值
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('2018-01-01 11:11:11.111222333 下午','YYYY-MM-DD HH12:MI:SS.FF9 AM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 AM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 AM TZR') FROM DUAL;
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('2018-01-01 11:11:11.111222333 下午','YYYY-MM-DD HH12:MI:SS.FF9 PM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 PM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 PM TZR') FROM DUAL;
    --含时区 12进度 得到存储时区 必须写上午和下午否则只能得到上午的值
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('2018-01-01 11:11:11.111222333 下午 +01:00','YYYY-MM-DD HH12:MI:SS.FF9 AM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 AM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 AM TZR') FROM DUAL;
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('2018-01-01 11:11:11.111222333 下午 +01:00','YYYY-MM-DD HH12:MI:SS.FF9 PM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 PM TZR'),'YYYY-MM-DD HH12:MI:SS.FF9 PM TZR') FROM DUAL;

    --24进度(转换格式中不需要指定对应12进度的AM/PM),自动转换出上午、下午和时区
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('2018-01-01 22:11:11.111222333','YYYY-MM-DD HH24:MI:SS.FF9 TZR'),'YYYY-MM-DD HH24:MI:SS.FF9 TZR'),'YYYY-MM-DD HH24:MI:SS.FF9 TZR') FROM DUAL;
    --24进度(转换格式中不需要指定对应12进度的AM/PM),自动转换出上午、下午和指定的时区
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('2018-01-01 22:11:11.111222333 +01:00','YYYY-MM-DD HH24:MI:SS.FF9 TZR'),'YYYY-MM-DD HH24:MI:SS.FF9 TZR'),'YYYY-MM-DD HH24:MI:SS.FF9 TZR') FROM DUAL;
    -------------------------------------
    --若转换与存储引擎中存储格式一致的数据(若数据库的sql引擎支持TO_CHAR且不指定格式,因为转化格式无中文的匹配模式),若不指定格式但数据库sql引擎支持此写法则可以这么些
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('01-1月-18 11:11:11.111222333 下午 +01:00'))),TO_TIMESTAMP_TZ('01-1月-18 11:11:11.111222333 下午 +01:00') FROM DUAL;
    SELECT TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP_TZ('01-1月-18 11:11:11.111222333 下午'))),TO_TIMESTAMP_TZ('01-1月-18 11:11:11.111222333 下午') FROM DUAL;
    -------------------------------------
    --开发案例,TO_CHAR后拼接得到时区差的TIMESTAMP(N) WITH LOCAL TIME ZONE数据类型的session(模拟时区)对应值
    --亚秒级的精度丢失解决方案 最小精度为纳秒
    SELECT SESSIONTIMEZONE,DBTIMEZONE,SYSTIMESTAMP,
    SYSTIMESTAMP+(SUBSTR(SESSIONTIMEZONE,2,2)+SUBSTR(SESSIONTIMEZONE,5,2)/60-SUBSTR(DBTIMEZONE,2,2)-SUBSTR(DBTIMEZONE,2,2)/60)/24 FROM DUAL;
    --逻辑
    SELECT SYSTIMESTAMP,
    TO_TIMESTAMP_TZ(TO_CHAR(SYSTIMESTAMP+SUBSTR(SESSIONTIMEZONE,2,2)/24+SUBSTR(SESSIONTIMEZONE,5,2)/24/60-SUBSTR(DBTIMEZONE,2,2)/24-SUBSTR(DBTIMEZONE,5,2)/24/60,'YYYY-MM-DD HH24:MI:SS')||SUBSTR(TO_CHAR(SYSTIMESTAMP,'YYYY-MM-DD HH24:MI:SS.FF6 TZR'),20),'YYYY-MM-DD HH24:MI:SS.FF6 TZR') FROM DUAL;

    --CREATE TABLE
    DROP TABLE VI.A34;

    CREATE TABLE A34 (
    ID NUMBER,
    NAME VARCHAR2(200) DEFAULT 'ABC' NOT NULL,
    V_TIMESTAMP_N TIMESTAMP(9) WITH TIME ZONE DEFAULT TO_TIMESTAMP('2018-01-01 10:10:10.111222333','YYYY-MM-DD HH24:MI:SS.FF9') NOT NULL,
    V_TIMESTAMP_LOCAL TIMESTAMP(9) WITH LOCAL TIME ZONE DEFAULT TO_TIMESTAMP('2018-01-01 10:10:10.111222333','YYYY-MM-DD HH24:MI:SS.FF9') NOT NULL
    );
    ALTER TABLE A34 ADD CONSTRAINT PK_A34 PRIMARY KEY(ID);

    --写入的TIMESTAMP(N) WITH LOCAL TIME ZONE数据类型数据保持不变
    DECLARE
    V_SESSIONTIME_SET VARCHAR2(200);
    BEGIN
    V_SESSIONTIME_SET:='''+'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,2,2)+0)),2,0)||':'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,5,2))+0),2,0)||'''';
    DBMS_OUTPUT.put_line(V_SESSIONTIME_SET);
    EXECUTE IMMEDIATE 'ALTER SESSION SET TIME_ZONE='||V_SESSIONTIME_SET;
    END;
    /

    DELETE FROM VI.A34;
    INSERT INTO A34(ID,NAME) SELECT 1,'AB1' FROM DUAL;
    INSERT INTO A34(ID,NAME) SELECT 2,'AB2' FROM DUAL;
    INSERT INTO A34(ID,NAME) SELECT 3,'AB3' FROM DUAL;
    COMMIT;

    SELECT SESSIONTIMEZONE,DBTIMEZONE,SYSDATE,T.* FROM VI.A34 T;

    --CREATE FUUNCTION
    --不启用RESULT_CACHE,若启用则结果集缓存与参数一一对应
    --用于客户端查询,转换结果返回TO_TIMESTAMP的数据类型
    CREATE OR REPLACE FUNCTION GET_TS_TZ_INC_CLIENT(
    V_OWNER VARCHAR2,
    V_TABLE_NAME VARCHAR2,
    V_COL_NAME VARCHAR2,
    V_INPUT VARCHAR2
    )
    RETURN VARCHAR2 /*RESULT_CACHE*/ AS
    PRAGMA AUTONOMOUS_TRANSACTION;
    N_DATA_SCALE NUMBER;
    V_SQL_EXE_TEMP VARCHAR2(1000);
    BEGIN
    BEGIN
    SELECT T.DATA_SCALE INTO N_DATA_SCALE FROM DBA_TAB_COLUMNS T WHERE T.OWNER=V_OWNER AND T.TABLE_NAME=V_TABLE_NAME AND T.COLUMN_NAME=V_COL_NAME;
    SELECT
    'TO_TIMESTAMP(TO_CHAR('||'TO_TIMESTAMP('||'SUBSTR('||V_INPUT||',1,20+'||N_DATA_SCALE||')'||',''YYYY-MM-DD HH24:MI:SS.FF'||N_DATA_SCALE||''')'||'+(SUBSTR('||'SESSIONTIMEZONE'||',2,2)+SUBSTR('||'SESSIONTIMEZONE'||',5,2)/60-SUBSTR('||'DBTIMEZONE'||',2,2)-SUBSTR('||'DBTIMEZONE'||',2,2)/60)/24,''YYYY-MM-DD HH24:MI:SS'')
    ||SUBSTR('||V_INPUT||',20,20+'||N_DATA_SCALE||'),''YYYY-MM-DD HH24:MI:SS.FF'||N_DATA_SCALE||''')'
    INTO V_SQL_EXE_TEMP
    FROM DUAL;
    EXCEPTION WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLCODE||'--'||SQLERRM||':'||CHR(10)||V_SQL_EXE_TEMP);
    RAISE_APPLICATION_ERROR(-20010,SQLCODE||'--'||SQLERRM||':'||CHR(10)||V_SQL_EXE_TEMP);
    END;
    RETURN V_SQL_EXE_TEMP;
    END GET_TS_TZ_INC_CLIENT;
    /

    --用于服务端查询,转换结果返回TO_CHAR的数据类型
    CREATE OR REPLACE FUNCTION GET_TS_TZ_INC_SERVER(
    V_OWNER VARCHAR2,
    V_TABLE_NAME VARCHAR2,
    V_COL_NAME VARCHAR2,
    V_INPUT VARCHAR2
    )
    RETURN VARCHAR2 /*RESULT_CACHE*/ AS
    PRAGMA AUTONOMOUS_TRANSACTION;
    N_DATA_SCALE NUMBER;
    V_SQL_EXE_TEMP VARCHAR2(1000);
    BEGIN
    BEGIN
    SELECT T.DATA_SCALE INTO N_DATA_SCALE FROM DBA_TAB_COLUMNS T WHERE T.OWNER=V_OWNER AND T.TABLE_NAME=V_TABLE_NAME AND T.COLUMN_NAME=V_COL_NAME;
    SELECT
    'TO_CHAR('||'TO_TIMESTAMP('||'SUBSTR('||V_INPUT||',1,20+'||N_DATA_SCALE||')'||',''YYYY-MM-DD HH24:MI:SS.FF'||N_DATA_SCALE||''')'||'+(SUBSTR('||'DBTIMEZONE'||',2,2)+SUBSTR('||'DBTIMEZONE'||',5,2)/60-SUBSTR('||'SESSIONTIMEZONE'||',2,2)-SUBSTR('||'SESSIONTIMEZONE'||',5,2)/60)/24,''YYYY-MM-DD HH24:MI:SS'')
    ||SUBSTR('||V_INPUT||',20,20+'||N_DATA_SCALE||')'
    INTO V_SQL_EXE_TEMP
    FROM DUAL;
    EXCEPTION WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLCODE||'--'||SQLERRM||':'||CHR(10)||V_SQL_EXE_TEMP);
    RAISE_APPLICATION_ERROR(-20010,SQLCODE||'--'||SQLERRM||':'||CHR(10)||V_SQL_EXE_TEMP);
    END;
    RETURN V_SQL_EXE_TEMP;
    END GET_TS_TZ_INC_SERVER;
    /

    --验证函数
    select SESSIONTIMEZONE,DBTIMEZONE,T.* from a34 t;
    select get_ts_tz_inc_client('VI','A34','V_TIMESTAMP_LOCAL','''2018-01-01 12:12:12.111222999''') from dual;
    select get_ts_tz_inc_SERVER('VI','A34','V_TIMESTAMP_LOCAL','''2018-01-01 12:12:12.111222999''') from dual;

    --SCRIPT TEST
    --CLIENT READ
    SELECT * FROM VI.A34 T;

    SELECT SESSIONTIMEZONE,DBTIMEZONE,'''+'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,2,2)+1)),2,0)||':'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,5,2))+10),2,0)||'''' FROM DUAL;
    --动态sql不能再ddl中赋值更新
    --ALTER SESSION SET TIME_ZONE='+'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,2,2)+1)),2,0)||':'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,5,2))+10),2,0)||'';
    --ALTER SESSION SET TIME_ZONE='+01:10'

    DECLARE
    V_SESSIONTIME_SET VARCHAR2(200);
    BEGIN
    V_SESSIONTIME_SET:='''+'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,2,2)+1)),2,0)||':'||LPAD(TO_CHAR(TO_NUMBER(SUBSTR(DBTIMEZONE,5,2))+10),2,0)||'''';
    DBMS_OUTPUT.put_line(V_SESSIONTIME_SET);
    EXECUTE IMMEDIATE 'ALTER SESSION SET TIME_ZONE='||V_SESSIONTIME_SET;
    END;
    /

    SELECT VI.GET_TS_TZ_INC_CLIENT('VI','A34','T_TIMESTAMP') FROM DUAL;

    SELECT SESSIONTIMEZONE,DBTIMEZONE,T.T_TIMESTAMP,
    TO_TIMESTAMP_TZ(TO_CHAR(T_TIMESTAMP+(SUBSTR('+01:10',2,2)+SUBSTR('+01:10',5,2)/60-SUBSTR('+00:00',2,2)-SUBSTR('+00:00',2,2)/60)/24,'YYYY-MM-DD HH24:MI:SS')
    ||SUBSTR(TO_CHAR(T_TIMESTAMP,'YYYY-MM-DD HH24:MI:SS.FF9 TZR'),20),'YYYY-MM-DD HH24:MI:SS.FF9 TZR')
    FROM VI.A34 T;

    -------------
    --SERVER WRITE 输入参数为把TIMESTAMP(N)转换为VARCHAR2
    SELECT VI.GET_TS_TZ_INC_SERVER('VI','A34','T_TIMESTAMP','2018-01-01 10:10:10.111222333') FROM DUAL;

    SELECT SESSIONTIMEZONE,DBTIMEZONE,TO_TIMESTAMP('2018-01-01 10:10:10.111222333','YYYY-MM-DD HH24:MI:SS.FF9') AS TO_TIMESTAMP_COMPARE,
    TO_TIMESTAMP_TZ(TO_CHAR(TO_TIMESTAMP('2018-01-01 10:10:10.111222333','YYYY-MM-DD HH24:MI:SS.FF9')+(SUBSTR('+00:00',2,2)+SUBSTR('+00:00',5,2)/60-SUBSTR('+01:10',2,2)-SUBSTR('+01:10',5,2)/60)/24,'YYYY-MM-DD HH24:MI:SS')
    ||SUBSTR(TO_CHAR(TO_TIMESTAMP('2018-01-01 10:10:10.111222333','YYYY-MM-DD HH24:MI:SS.FF9'),'YYYY-MM-DD HH24:MI:SS.FF9 TZR'),20),'YYYY-MM-DD HH24:MI:SS.FF9 TZR')
    FROM DUAL;

    -以下为拓展部分,当结果集缓存不完全依赖于参数时的风险需要消除
    --DETERMINISTIC FUNCTION 确定性参数结果集函数
    CREATE OR REPLACE FUNCTION GET_TIMESTAMP_N(
    N_ID NUMBER
    )
    RETURN VARCHAR2 DETERMINISTIC/*RESULT_CACHE*/ AS
    PRAGMA AUTONOMOUS_TRANSACTION;
    V_NAME VARCHAR2(40);
    BEGIN
    SELECT T.NAME INTO V_NAME FROM VI.A34 T WHERE T.ID=N_ID;
    RETURN V_NAME;
    END GET_TIMESTAMP_N;
    /

    --RESULT_CACHE FUNCTION 结果集缓存函数
    CREATE OR REPLACE FUNCTION GET_TIMESTAMP_N(
    N_ID NUMBER
    )
    RETURN VARCHAR2 RESULT_CACHE AS
    PRAGMA AUTONOMOUS_TRANSACTION;
    V_NAME VARCHAR2(40);
    BEGIN
    SELECT T.NAME INTO V_NAME FROM VI.A34 T WHERE T.ID=N_ID;
    RETURN V_NAME;
    END GET_TIMESTAMP_N;
    /

  • 相关阅读:
    Log4net快速搭建
    WebAPI中Area的使用
    (三)Redis for StackExchange.Redis
    (二)Redis for 阿里云公网连接
    Python+CGI,在Windows上快速部署Python到IIS
    腾讯云
    UIView添加事件
    Sublime Text Packages Control 安装
    乎乎测试
    常用第三方类库
  • 原文地址:https://www.cnblogs.com/buffercache/p/10071919.html
Copyright © 2011-2022 走看看