我是靠谱客的博主 瘦瘦大米,最近开发中收集的这篇文章主要介绍Oracle12C--数据类型划分(二十七),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

知识点的梳理:

  • Oracle中的varchar2与其他数据库的varchar完全一样;
  • 使用UNICODE编码最大的方便之处是统一了字符与汉字的长度。这样在进行文字处理时会更加方便。但是,由于所有的字母都会按照十六进制保存,所以会存在浪费空间的问题

      

  • 四类数据类型
    • 标量类型(SCALAR,或称基本数据类型):用于保存单个值,例如字符串,数字,日期,布尔;
    • 复合类型(COMPOSITE):复合类型可以在内部存放多种数值,类似于多个变量的集合,例如记录类型,嵌套表,索引表,可变数组等;
    • 引用类型(REFERENCE):用于指向另一个不同对象,例如REF CURSOR,REF
    • LOB类型:大数据类型,最多可以存储4GB的信息,主要用来处理二进制数据;
  • 标量类型
    • 标量类型也被称为基本数据类型
    • 常见标量类型

  • 数值型
    • NUMBER数据类型
      • 采用十进制类型,需将十进制转为二进制进行计算
        • 定义整型:NUMBER(n);
        • 定义浮点型数据:NUMBER(m,n)
      • 实例1:定义NUMBER变量

DECLARE

v_x NUMBER(3) ; -- 最多只能为3位数字

v_y NUMBER(5,2) ; -- 3位整数,2位小数

BEGIN

v_x := -500 ;

v_y := 999.88 ;

DBMS_OUTPUT.put_line('v_x = ' || v_x) ;

DBMS_OUTPUT.put_line('v_y = ' || v_y) ;

DBMS_OUTPUT.put_line('加法运算:' || (v_x + v_y)) ; -- 整数 + 浮点数 = 浮点数

END ;

/

效果:
v_x = -500

v_y = 999.88

加法运算:499.88

  • BINARY_INTEGERPLS_INTEGER
    • 说明:
      • 两者具有相同的范围长度。与NUMBER比较,占用的范围更小;
      • 采用二进制补码存储,运算性能比NUMBER高;
    • 两者区别:
      • BINARY_INTEGER操作的数据大于其数据范围时,会自动转换为NUMBER型进行保存;
      • PLS_INTEGER操作的数据大于范围时,会抛出异常信息
    • 示例1:验证PLS_INTEGER操作

DECLARE

v_pls1 PLS_INTEGER := 100 ;

v_pls2 PLS_INTEGER := 200 ;

v_result PLS_INTEGER ;

BEGIN

v_result := v_pls1 + v_pls2 ;

DBMS_OUTPUT.put_line('计算结果:' || v_result) ;

END ;

/

计算结果:300

  • BINARY_FLOATBINARY_DOUBLE
    • 两者比NUMBER节约空间,同时范围更大,采用二进制存储数据;
    • 示例1:验证BINARY_DOUBLE操作

DECLARE

v_float BINARY_FLOAT := 8909.51F ;

v_double BINARY_DOUBLE := 8909.51D ;

BEGIN

v_float := v_float + 1000.16 ;

v_double := v_double + 1000.16 ;

DBMS_OUTPUT.put_line('BINARY_FLOAT变量内容:' || v_float) ;

DBMS_OUTPUT.put_line('BINARY_DOUBLE变量内容:' || v_double) ;

END ;

/

计算结果:

BINARY_FLOAT变量内容:9.90966992E+003

BINARY_DOUBLE变量内容:9.9096700000000001E+003

  • 两者定义的常量:这些常量只能在PL/SQL中使用。这些常量分别表示BINARY_FLOATBINARY_DOUBLE的数据范围,同时针对非数字与超过其类型最大值的数据标记

    • 示例2:观察表示范围的常量内容

DECLARE

BEGIN

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MIN_NORMAL = ' || BINARY_FLOAT_MIN_NORMAL) ;

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MAX_NORMAL = ' || BINARY_FLOAT_MAX_NORMAL) ;

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MIN_SUBNORMAL = ' || BINARY_FLOAT_MIN_SUBNORMAL) ;

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MAX_SUBNORMAL = ' || BINARY_FLOAT_MAX_SUBNORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MIN_NORMAL = ' || BINARY_DOUBLE_MIN_NORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MAX_NORMAL = ' || BINARY_DOUBLE_MAX_NORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MIN_SUBNORMAL = ' || BINARY_DOUBLE_MIN_SUBNORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MAX_SUBNORMAL = ' || BINARY_DOUBLE_MAX_SUBNORMAL) ;

END ;

/

运行结果:

1、BINARY_FLOAT_MIN_NORMAL = 1.17549435E-038

1、BINARY_FLOAT_MAX_NORMAL = 3.40282347E+038

1、BINARY_FLOAT_MIN_SUBNORMAL = 1.40129846E-045

1、BINARY_FLOAT_MAX_SUBNORMAL = 1.17549421E-038

2、BINARY_DOUBLE_MIN_NORMAL = 2.2250738585072014E-308

2、BINARY_DOUBLE_MAX_NORMAL = 1.7976931348623157E+308

2、BINARY_DOUBLE_MIN_SUBNORMAL = 4.9406564584124654E-324

2、BINARY_DOUBLE_MAX_SUBNORMAL = 2.2250738585072009E-308

  • 示例3超过范围的计算

DECLARE

BEGIN

DBMS_OUTPUT.put_line('超过范围计算的结果:' ||

BINARY_DOUBLE_MAX_NORMAL * BINARY_DOUBLE_MAX_NORMAL) ;

DBMS_OUTPUT.put_line('超过范围计算的结果:' ||

BINARY_DOUBLE_MAX_NORMAL / 0) ;

END ;

/

运行结果:

超过范围计算的结果:Inf

超过范围计算的结果:Inf

  • 字符型
    • CHARVARCHAR2
      • 说明:
        • CHAR采用定长方式保存字符串。如果用户设置的内容不足其定义长度,则会自动补充空格;
        • VARCHAR2是可变字符串。如果设置的内容不足其长度,也不会为其补充内容;
      • 示例1:观察CHAR和VARCHAR2的区别

DECLARE

v_info_char CHAR(10) ;

v_info_varchar VARCHAR2(10) ;

BEGIN

v_info_char := 'MLDN' ; -- 长度不足10

v_info_varchar := 'java' ; -- 长度不足10

DBMS_OUTPUT.put_line('v_info_char内容长度:' || LENGTH(v_info_char)) ;

DBMS_OUTPUT.put_line('v_info_varchar内容长度:' || LENGTH(v_info_varchar)) ;

END ;

/

运行结果:

v_info_char内容长度:10

v_info_varchar内容长度:4

  • NCHARNVARCHAR2
    • 两者的特性与CHARVARCHAR2一样。区别在于它们保存的数据为UNICODE编码,中文与英文都会变为十六进制编码保存;
    • 示例1:验证NCHAR和NVARCHAR2

DECLARE

v_info_nchar NCHAR(10) ;

v_info_nvarchar NVARCHAR2(10) ;

BEGIN

v_info_nchar := 'CSDN' ; -- 长度不足10

v_info_nvarchar := 'java高端培训' ; -- 长度不足10

DBMS_OUTPUT.put_line('v_info_nchar内容长度:' || LENGTH(v_info_nchar)) ;

DBMS_OUTPUT.put_line('v_info_nvarchar内容长度:' || LENGTH(v_info_nvarchar)) ;

END ;

/

运行结果:

v_info_nchar内容长度:10

v_info_nvarchar内容长度:8

  • LONGLONG RAW
    • 两者用于向后兼容;
    • LONG说明:
      • 使用LONG的地方都会使用CLOBNCLOB
      • LONG用于存储字符流;
      • 可以使用"UTL_RAW.cast_to_varchar2(RAW数据)"函数,将RAW转为字符串
    • LONG RAW说明:
      • 使用LONG RAW的地方都替换为BLOBBILE
      • LONG RAW用于存储二进制数据流
      • LONG RAW变量设置内容,要使用"UTL_RAW.cast_to_raw(字符串)"进行转换;
    • 示例1使用LONGLONG RAW操作

DECLARE

v_info_long LONG ;

v_info_longraw LONG RAW ;

BEGIN

v_info_long := 'CSDN' ; -- 直接设置字符串

v_info_longraw := UTL_RAW.cast_to_raw('JAVA高端培训') ; -- 将字符串变为RAW

DBMS_OUTPUT.put_line('v_info_long内容:' || v_info_long) ;

DBMS_OUTPUT.put_line('v_info_longraw内容:' || UTL_RAW.cast_to_varchar2(v_info_longraw)) ;

END ;

/

运行结果:

v_info_long内容:CSDN

v_info_longraw内容:JAVA高端培训

  • ROWIDUROWID
    • ROWID表示的是一条数据的物理行地址,由18个字符组合而成,与ROWID伪列功能相同;
    • UROWID具备ROWID的功能,还增加了一个逻辑行地址,在PL/SQL中应将所有的ROWID交给UROWID管理;
    • 示例1使用ROWIDUROWID

DECLARE

v_emp_rowid ROWID ;

v_emp_urowid UROWID ;

BEGIN

SELECT ROWID INTO v_emp_rowid FROM emp WHERE empno=7369 ; -- 取得ROWID

SELECT ROWID INTO v_emp_urowid FROM emp WHERE empno=7369 ; -- 取得ROWID

DBMS_OUTPUT.put_line('7369雇员的ROWID = ' || v_emp_rowid) ;

DBMS_OUTPUT.put_line('7369雇员的UROWID = ' || v_emp_urowid) ;

END ;

/

运行结果:

7369雇员的ROWID = AAAX0rAAGAAAaRsAAA

7369雇员的UROWID = AAAX0rAAGAAAaRsAAA

  • 日期型
    • DATE数据类型
      • 用来存储日期时间数据;
      • 可通过SYSDATESYSTIMESTAMP两个伪列来获取当前的日期时间;
      • 主要字段索引:
      • 示例1定义DATE型变量

DECLARE

v_date1 DATE := SYSDATE ;

v_date2 DATE := SYSTIMESTAMP ;

v_date3 DATE := '19-9-1981' ;

BEGIN

DBMS_OUTPUT.put_line('日期数据:' || TO_CHAR(v_date1,'yyyy-mm-dd hh24:mi:ss')) ;

DBMS_OUTPUT.put_line('日期数据:' || TO_CHAR(v_date2,'yyyy-mm-dd hh24:mi:ss')) ;

DBMS_OUTPUT.put_line('日期数据:' || TO_CHAR(v_date3,'yyyy-mm-dd hh24:mi:ss')) ;

END ;

/

运行结果:

日期数据:2017-02-15 16:33:47

日期数据:2017-02-15 16:33:47

日期数据:1981-09-19 00:00:00

  • TIMESTAMP数据类型
    • 该类型与DATE的区别在于,可以提供更为准确的时间。但是要使用SYSTIMESTAMP伪列来为其赋值;
      • 如果只是使用SYSDATE,那么TIMESTAMPDATE没有任何区别;
    • 示例1定义TIMESTAMP型变量

DECLARE

v_timestamp1 TIMESTAMP := SYSDATE ;

v_timestamp2 TIMESTAMP := SYSTIMESTAMP ;

v_timestamp3 TIMESTAMP := '19-9-1981' ;

BEGIN

DBMS_OUTPUT.put_line('日期数据:' || v_timestamp1) ;

DBMS_OUTPUT.put_line('日期数据:' || v_timestamp2) ;

DBMS_OUTPUT.put_line('日期数据:' || v_timestamp3) ;

END ;

/

运行结果:

日期数据:15-2月 -17 04.37.40.000000 下午

日期数据:15-2月 -17 04.37.40.372000 下午

日期数据:19-9月 -81 12.00.00.000000 上午

  • TIMESTAMP的两个扩充子类型:
    • TIMESTAMP WITH TIME ZONE包含与格林威治时间的时区偏移量

DECLARE

v_timestamp TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP ;

BEGIN

DBMS_OUTPUT.put_line(v_timestamp) ;

END ;

/

运行结果:
15-2月 -17 04.39.28.603000 下午 +08:00

  • TIMESTAMP WITH LOCAL TIME ZONE:不管是何种时区的数据,都使用当前数据库的时区;

DECLARE

v_timestamp TIMESTAMP WITH LOCAL TIME ZONE := SYSTIMESTAMP ;

BEGIN

DBMS_OUTPUT.put_line(v_timestamp) ;

END ;

/

运行结果:
15-2月 -17 04.40.43.309000 下午

  • INTERVAL数据类型
    • 该类型可以保存两个时间戳之间的时间间隔,此类型分为两个子类型:
      • INTERVAL YEAR[(年的精度)] TO MONTHS:保存的和操作年与月之间的时间间隔,用户可以设置年的数据精度。默认值为2
        • 赋值格式:'年-月'
      • INTERVAL DAY[(天的精度)] TO SECEND[(秒的精度)]:保存和操作天,时,分,秒之间的时间间隔,默认为2。秒的默认值为6
        • 赋值格式:'时:分:秒.毫秒'
      • 当取得时间间隔后,可利用下列公式进行计算:

    • 示例1:定义INTERVAL YEAR TO MONTHS类型变量

DECLARE

v_interval INTERVAL YEAR(3) TO MONTH := INTERVAL '27-09' YEAR TO MONTH ;

BEGIN

DBMS_OUTPUT.put_line('时间间隔:' || v_interval) ;

DBMS_OUTPUT.put_line('当前时间戳 + 时间间隔:' || (SYSTIMESTAMP + v_interval)) ;

DBMS_OUTPUT.put_line('当前日期 + 时间间隔:' || (SYSDATE + v_interval)) ;

END ;

/

运行结果:

时间间隔:+027-09

当前时间戳 + 时间间隔:15-11月-44 04.47.58.902000000 下午 +08:00

当前日期 + 时间间隔:15-11月-44

  • 示例2定义INTERVAL DAY TO SECOND类型变量

DECLARE

v_interval INTERVAL DAY(6) TO SECOND (3) := INTERVAL '8 18:19:27.367123909' DAY TO SECOND;

BEGIN

DBMS_OUTPUT.put_line('时间间隔:' || v_interval) ;

DBMS_OUTPUT.put_line('当前时间戳 + 时间间隔:' || (SYSTIMESTAMP + v_interval)) ;

DBMS_OUTPUT.put_line('当前日期 + 时间间隔:' || (SYSDATE + v_interval)) ;

END ;

/

运行结果:

时间间隔:+000008 18:19:27.367

当前时间戳 + 时间间隔:24-2月 -17 11.08.00.803000000 上午 +08:00

当前日期 + 时间间隔:24-2月 -17

  • 布尔型
    • 该类型保存TRUE,FALSE,NULL
    • 示例1定义布尔型变量

DECLARE

v_flag BOOLEAN ;

BEGIN

v_flag := true ;

IF v_flag THEN

DBMS_OUTPUT.put_line('条件满足。') ;

END IF ;

END ;

/

运行结果:
条件满足。

  • 子类型
    • 在某一标量类型的基础上定义更多约束,从而创建一个新的类型,这种新类型被称为子类型;
    • 创建语法:

subtype 子类型名称 is 父数据类型[(约束)] [not null];

在定义子类型的时候必须设置好父数据类型。父类型可以是Oracle的各种数据类型

  • 示例1定义NUMBER子类型

DECLARE

SUBTYPE score_subtype IS NUMBER(5,2) NOT NULL ;

v_score score_subtype := 99.35 ; --依据score_subtype类型为v_score变量赋值为99.35

BEGIN

DBMS_OUTPUT.put_line('成绩为:' || v_score) ;

END ;

/

运行结果:
成绩为:99.35
分析:定义了一个
score_subtype的子类型,明确了精度。且不为NULL。该子类型定义完成后,实际上就相当于
定义了一个新类型,所以依然要依据此类型定义变量。但由于定义子类型时设置了不为
NULL,所以在定义变量时要设置内容,
且不能超过要求精度;

  • 示例2定义VARCHAR2子类型

DECLARE

SUBTYPE string_subtype IS VARCHAR2(200) ;

v_company string_subtype ;--声明一个子类型为 string_subtype的变量v_company

BEGIN

v_company := 'csdnwww.csdn.cn' ;

DBMS_OUTPUT.put_line(v_company) ;

END ;

/

运行结果:
csdn(www.csdn.cn)
分析:在声明子类型时,没有设置
NOT NULL约束,所以在DECLARE中不用强制赋值

最后

以上就是瘦瘦大米为你收集整理的Oracle12C--数据类型划分(二十七)的全部内容,希望文章能够帮你解决Oracle12C--数据类型划分(二十七)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部