--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;
/

TIMESTAMPN(N) WITH LOCAL TIMEZONE数据类型转换的更多相关文章

  1. SparkSql 数据类型转换

    SparkSql 数据类型转换 1.SparkSql数据类型 1.1数字类型 1.2复杂类型 2.Spark Sql数据类型和Scala数据类型对比 3.Spark Sql数据类型转换案例 3.1获取 ...

  2. 生成二维码 加密解密类 TABLE转换成实体、TABLE转换成实体集合(可转换成对象和值类型) COOKIE帮助类 数据类型转换 截取字符串 根据IP获取地点 生成随机字符 UNIX时间转换为DATETIME\DATETIME转换为UNIXTIME 是否包含中文 生成秘钥方式之一 计算某一年 某一周 的起始时间和结束时间

    生成二维码 /// <summary>/// 生成二维码/// </summary>public static class QRcodeUtils{private static ...

  3. 04springMVC数据类型转换

    数据类型转换简介 Spring Web MVC中的数据类型转换 内建的类型转换器 自定义类型转换器 1      数据类型转换简介 当从页面提交数据到后台Action的时候,通过请求发送的数据,通常都 ...

  4. lua数组和数据类型转换

    一.lua数组 Lua数组大小不固定,下标是从  1开始. --数组 arr={"aaa","bbb","ccc"} --使用数值 for通 ...

  5. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

  6. Sql Server函数全解<三>数据类型转换函数和文本图像函数

    阅读目录 一:数据类型转换函数 二:文本和图像函数 一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近的值是有效的,比如int和flo ...

  7. JS 数据类型转换

    JS 数据类型转换 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把 ...

  8. 使用变量 数据类型转换 逻辑控制语句(begin ...end; case...end; if...else; while)

    一:变量 变量分为局部变量和全局变量  (全局变量是系统自定的,是不可手动给值的,若想自己定义全局变量可考虑创建全局临时表!) 局部变量的定义:  declare @变量名  数据类型 (局部变量只能 ...

  9. Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)

    上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...

随机推荐

  1. ButterKnife官方使用例子

    Introduction Annotate fields with @BindView and a view ID for Butter Knife to find and automatically ...

  2. jsp快速开始

    [greeting.jsp] <%@ page contentType="text/html;charset=UTF-8" language="java" ...

  3. 利用openpyxl模块来操作Excel

    python 读写 excel 有好多选择,但是,方便操作的库不多,在我尝试了几个库之后,我觉得两个比较方便的库分别是 xlrd/xlwt.openpyxl. 之所以推荐两个库是因为这两个库分别操作的 ...

  4. 从一个数组对象中取key 和value组成一个新的对象

    const type = [ {key:'TimeWeiDu',value:'时间维度'}, {key:'TranType',value:'交易类型'}, {key:'OrderType',value ...

  5. luogu P4770 [NOI2018]你的名字

    传送门 upd 19.4.24: WC这个做法真的有问题,不往回跳会WA是因为一开始跳到了S[1...l-1]所对应的点,然后往后接字符的时候可能会因为不在正确的endpos中,然后往回跳过头,其实一 ...

  6. 第20月第29天 cocoa抽象工厂 cocoapods组件化 cocoapods升级

    1. 在 Cocoa Touch 框架中,类簇是抽象工厂模式在 iOS 下的一种实现,以 NSArray 举例,将原有的 alloc+init 拆开写: id obj1 = [NSArray allo ...

  7. MLE

    独立同分布的采样x1,x2,…,xn,θ为模型参数,f为我们所使用的模型.参数为θ的模型f产生上述采样可表示为 f(x1,x2,…,xn|θ)=πf(xi|θ) 已知的为x1,x2,…,xn,未知为θ ...

  8. Centos7安装美团SQL优化工具SQLAdvisor

    1 下载源码 git clone https://github.com/Meituan-Dianping/SQLAdvisor.git 2 安装依赖环境 yum install cmake libai ...

  9. python 的基础 学习 11天 作业题

    1.整理函数相关知识点,写博客 2.写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者. def func1(argv): li = [] for i in r ...

  10. 20165237 2017-2018-2 《Java程序设计》第7周学习总结

    20165237 2017-2018-2 <Java程序设计>第7周学习总结 教材学习内容总结 1.MySQL数据库管理系统,简称MySQL,是世界上最流行的开源数据库管理系统. 2.启动 ...