--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. SQL Server Management Studio 使用技巧

    Ø  前言 本文主要介绍 SQL Server Management Studio 工具的使用,相信很多开发人员都比较熟悉此工具,特别是做 C# 开发的程序员,基本上都会经常使用该工具,当然也可以使用 ...

  2. LINQ to SQL 中 Concat、Union、Intersect、Except 方法的使用

    Ø  前言 LINQ to SQL 中需要对两个或多个数据集进行操作,比如:合并.取交集等,主要使用下面四个方法,这四个方法都是 System.Linq.IQueryable<out T> ...

  3. 常用.net反编译替换正则表达式

    .set_([^\(]*) .$ = ------------------ .get_([^\(]*)\(\) .$ ------------------ .get_Item\(([a-z|-]+)\ ...

  4. 信号量Semaphore

    信号量说简单点就是为了线程同步,或者说是为了限制线程能运行的数量. 那它又是怎么限制线程的数量的哩?是因为它内部有个计数器,比如你想限制最多5个线程运行,那么这个计数器的值就会被设置成5,如果一个线程 ...

  5. Nginx正反向代理、负载均衡等功能实现配置

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   系统环境: VirtualBox Manager Centos6.4 nginx1.10.0 IP对应的机器名: IP ...

  6. MacOS英文版Google浏览器添加印象笔记剪藏插件

    1 切换到国内的Google应用商店安装 https://chrome.google.com/webstore/detail/evernote-web-clipper/pioclpoplcdbaefi ...

  7. linux全部替换命令学习

    :%s/准备替换内容/新内容/g 可以使用 # 作为分隔符,此时中间出现的 / 不会作为分隔符 :%s#vivian/#sky/#g 替换 vivian/ 为 sky/ :%s+/oradata/ap ...

  8. 数组去重的4种方法(Which one is the fastest???嘻嘻嘻....)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 【Git】Git常见错误

    错误1.fatal: refusing to merge unrelated histories 致命的:拒绝合并不相关的历史 原因:比如我本地分支是V1.0,我现在想要合并远程master分支上的内 ...

  10. var/let/const区别何在??(转载)

    原文地址:http://www.cnblogs.com/liuhe688/p/5845561.html let和const有很多相似之处,先说一说let吧. 1. let添加了块级作用域 我们知道,J ...