知识库✳

教程与手册

全部教程
  1. 01Oracle 函数手册
  2. 02性能优化手册
  3. 03Linux Shell
  4. 04Oracle 学习与演练
  5. 05网络基础学习
  6. 06数据治理与管理
返回个人网站
甲Oracle 学习教程从 SQL 到 PL/SQL 与运维
首页课程目录搜索演练场
知识库

已完成 0 / 22 章

模块一 · 入门与准备

  • 01Oracle 数据库体系结构
  • 02环境安装与连接方式
  • 03SQL*Plus 与常用工具

模块二 · SQL 查询基础

  • 04SELECT 查询基础
  • 05过滤与排序
  • 06单行函数
  • 07多表连接
  • 08分组聚合与 HAVING
  • 09子查询

模块三 · 数据与对象

  • 10DML 与事务控制
  • 11表与数据类型
  • 12约束
  • 13索引与执行计划
  • 14视图、序列与同义词

模块四 · PL/SQL 编程

  • 15PL/SQL 块与变量
  • 16流程控制与游标
  • 17存储过程与函数
  • 18触发器
  • 19异常处理

模块五 · 运维与进阶

  • 20用户与权限管理
  • 21表空间与存储管理
  • 22备份与恢复
❖

Oracle 学习教程

返回个人网站知识库

示例代码基于 Oracle AI Database 26ai / 23ai,查询示例使用官方 HR 示例方案。

以 Next.js 16 · Tailwind CSS v4 · HeroUI v3 装帧

11
  1. 首页
  2. 课程目录
  3. 表与数据类型

第 11 章◆进阶◆建议 45 分钟◆模块三 · 数据与对象

表与数据类型

建表、选类型、改结构:数据类型选错会在后期带来很大的迁移成本。

学完这一章,你应该能

  • 为不同业务选择合适的数据类型
  • 掌握 CTAS 与 ALTER TABLE 的常见操作
  • 理解 VARCHAR2 字符语义与 NUMBER 精度
  • 知道临时表的正确用法

11.1常用数据类型

  • VARCHAR2(n):变长字符串,最常用;必须指定长度
  • CHAR(n):定长,不足补空格,只适合长度固定的编码(如性别、国家码)
  • NUMBER(p,s):p 是总位数,s 是小数位;NUMBER(10,2) 适合金额
  • DATE:日期 + 时间,精确到秒
  • TIMESTAMP:可到小数秒并带时区(TIMESTAMP WITH TIME ZONE)
  • CLOB / BLOB:大文本 / 二进制。容量上限不是 4GB,而是 (4GB−1) × 块大小,随表空间块大小在 8TB 到 128TB 之间
  • RAW(n):二进制,常用于存哈希值或 UUID
  • BOOLEAN:23ai 起原生支持

提示 金额字段别用 FLOAT/BINARY_DOUBLE,二进制浮点会有舍入误差。用 NUMBER(p,2)。同样,主键别用 VARCHAR2 存数字。

11.2建表与 CTAS

  • CTAS 不复制主键/唯一/外键/检查约束、索引、默认值和分区;但会复制显式创建且为 NOT DEFERRABLE + VALIDATE 的 NOT NULL 约束,隐式 NOT NULL(主键带出的)不复制
  • VARCHAR2 的长度语义由初始化参数 NLS_LENGTH_SEMANTICS 决定(缺省 BYTE,一个中文常占 3 字节);要确保按字符计数,显式写 VARCHAR2(200 CHAR)
  • CTAS 是 DDL,会隐式提交
标准建表与复制结构/数据
CREATE TABLE employees_demo (
  employee_id   NUMBER(6)      NOT NULL,
  last_name     VARCHAR2(25)   NOT NULL,
  email         VARCHAR2(25),
  hire_date     DATE           DEFAULT SYSDATE,
  salary        NUMBER(8,2),
  remarks       VARCHAR2(200 CHAR),   -- CHAR 语义:按字符计数,中文更友好
  CONSTRAINT pk_emp_demo PRIMARY KEY (employee_id)
);

-- CTAS:只复制结构不要数据
CREATE TABLE employees_empty AS
SELECT * FROM employees WHERE 1 = 0;

-- 复制结构和数据
CREATE TABLE employees_copy AS
SELECT employee_id, last_name, salary FROM employees;

只作示例阅读:5 行写入限制下只开放单独创建普通空表;CTAS、删表、清空表、改结构、触发器和存储程序不允许执行。请在独立学习数据库中练习。

11.3修改表结构

ALTER TABLE 常见操作
-- 加列(有默认值时,11g+ 可做到不重写全表)
ALTER TABLE employees_demo ADD (phone VARCHAR2(20));

-- 改类型与长度(表为空或长度放大时才容易成功)
ALTER TABLE employees_demo MODIFY (email VARCHAR2(50));

-- 改列名
ALTER TABLE employees_demo RENAME COLUMN phone TO mobile;

-- 改表名与删表改用一张临时表演示,
-- 以免把后面章节还要用的 employees_demo 改掉
CREATE TABLE emp_scratch AS SELECT * FROM employees_demo WHERE 1 = 0;
RENAME emp_scratch TO emp_demo;

-- 删列与置为未使用(大表删除列耗时长,可先标记)
ALTER TABLE emp_demo SET UNUSED COLUMN remarks;
ALTER TABLE emp_demo DROP UNUSED COLUMNS;

-- 删除表(默认进回收站,可用 FLASHBACK TABLE ... TO BEFORE DROP 恢复)
DROP TABLE emp_demo;

-- 想彻底删除、不进回收站就用下面这条(与上一条二选一,不要连着执行)
-- DROP TABLE emp_demo PURGE;

只作示例阅读:5 行写入限制下只开放单独创建普通空表;CTAS、删表、清空表、改结构、触发器和存储程序不允许执行。请在独立学习数据库中练习。

提示 生产库改大表结构要评估锁与耗时。DROP TABLE 默认进回收站,用 FLASHBACK TABLE ... TO BEFORE DROP 可以救回来,这也是别急着加 PURGE 的原因。

11.4临时表

Oracle 的临时表(GTT)是「一次定义、长期存在」的,数据则按会话或事务隔离。这和 SQL Server 的 #temp 概念不同,初学者经常误以为要每次创建。

  • 临时表定义是全局共享的,数据是会话私有的
  • 临时表也会产生 redo(但比普通表少)和 undo,不能当内存表用
  • 数据量小的中间结果,优先考虑 WITH 子句而不是临时表
会话级临时表
CREATE GLOBAL TEMPORARY TABLE gtt_cart (
  session_item_id NUMBER,
  item_name       VARCHAR2(100),
  qty             NUMBER
) ON COMMIT PRESERVE ROWS;
-- 会话结束时清空

-- 改成事务级:ON COMMIT DELETE ROWS(提交即清空)

只作示例阅读:5 行写入限制下只开放单独创建普通空表;CTAS、删表、清空表、改结构、触发器和存储程序不允许执行。请在独立学习数据库中练习。

练习

3 题 · 先自己写,再展开对照

参考答案

CREATE TABLE employees_empty AS
SELECT * FROM employees WHERE 1 = 0;

只作示例阅读:5 行写入限制下只开放单独创建普通空表;CTAS、删表、清空表、改结构、触发器和存储程序不允许执行。请在独立学习数据库中练习。

自评要点

  • CTAS 加恒假条件
  • 知道 CTAS 不会复制索引、主键/外键/唯一/检查约束和默认值

参考答案

会复制:显式创建且状态为 NOT DEFERRABLE + VALIDATE 的 NOT NULL 约束
(要求该列是被直接选取的,而不是包在表达式里)。

不会复制:主键、唯一、外键、检查约束、索引、默认值、分区、加密属性。

另外,由主键等「隐式」带出来的 NOT NULL 也不会复制。
所以纯靠 CTAS 建出来的表,约束是残缺的,需要手工补齐。

自评要点

  • 知道显式 NOT NULL 会被复制(很多人以为不会)
  • 知道 PK/UK/FK/CHECK/索引/默认值都不复制

参考答案

用 NUMBER —— 金额通常写 NUMBER(12,2)。

不用 FLOAT/BINARY_DOUBLE 的原因:它们是二进制浮点,无法精确表示大多数
十进制小数,累加或比较会出现舍入误差,对账时就会出现「差几分钱」的问题。
NUMBER 是十进制精确数值类型。

自评要点

  • 选 NUMBER 并给出精度 (p,s)
  • 指出二进制浮点的舍入误差
← 上一章

DML 与事务控制

下一章 →

约束