开发者工具 · 数据库

Oracle SQL 速查

DDL/函数/分析函数

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 57 次使用
ORACLE COMMANDS

Oracle 命令速查

DDL / 函数 / 分析函数 / PL/SQL

第一节

关于本工具

About

写 CREATE TABLE 时总记不清 VARCHAR 的最大长度、DECIMAL 的精度声明,或者分析函数中 PARTITION BY 与 ORDER BY 的执行顺序。这个速查表把 Oracle 常用的 DDL 语法、内置函数和分析函数按类别列出来,每条附带一个可运行的示例。数据全部预置在页面中,不向任何服务器发送请求,离线环境也能查。

使用场景

表分区方案抉择

DBA 老张在凌晨两点接到业务通知,下月订单表预计增长 5000 万行,需要当天确定分区策略。是范围分区按月份切、还是列表分区按区域切、或是哈希分区均匀打散?他打开速查页,在「DDL 分区」区段找到各分区的建表语法与适用说明,对比后选定「范围-哈希复合分区」,当场拼出建表 DDL,赶在晨会前提交了方案。

分析函数排位次

运营总监需要从 120 个门店的周销售额中,提取「每个区域销售额前三的门店」用于发放奖金。用自关联子查询写出来的 SQL 又长又慢,跑一次要 8 分钟。他在分析函数区找到 RANK() 与 DENSE_RANK() 的语法示例,5 分钟内写完带 PARTITION BY region 的 SQL,执行时间降到 12 秒,数据直接导出给财务。

字符串清洗脱敏

测试组小刘拿到一批生产环境脱敏后的手机号,要求将中间四位替换为星号,且保留前三位和后四位的原始值。他记得 Oracle 有 LPAD、RPAD 和 SUBSTR,但组合起来总报错。在函数区找到字符串函数的完整参数列表与返回值说明,对照着写出 `SELECT SUBSTR(phone,1,3) || '****' || SUBSTR(phone,8,4)`,一次通过 Code Review。

时间窗口聚合统计

金融风控分析师需要统计过去 7 天每个用户「每日累计交易金额」以及「与前一天相比的环比增长率」。用普通 GROUP BY 只能拿到每日汇总,算不出累计值。他在分析函数区找到 SUM() OVER (ORDER BY day ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) 的写法,配合 LAG() 函数,一条 SQL 输出了 30 天滚动窗口与环比,省去了在 Excel 里手动拉公式的 2 小时。

索引字段类型抉择

开发小王在给一个 300 万行的日志表建索引,字段是 timestamp 类型。他纠结是用 B-tree 还是位图索引,以及是否要加函数索引把时间转成日期。在 DDL 索引区看到「位图索引适合低基数列(如性别、状态)」的说明,且函数索引的创建语法与限制一目了然。他决定对 timestamp 字段建普通 B-tree 索引,对状态字段建位图索引,第二天查询性能提升 70%。

第二节

使用指南

Getting Started

使用步骤

  1. 1在左侧分类栏点选「DDL」「函数」或「分析函数」标签,右侧列表自动筛选对应语法条目
  2. 2点击任一语法条目(如 CREATE TABLE),上方代码区显示完整语法模板与参数说明
  3. 3在代码区直接编辑参数(如表名、列类型),修改后下方「示例」区域同步更新对应 SQL 片段
  4. 4点击代码区右上角「复制」按钮,将当前 SQL 语句复制到剪贴板,供粘贴到 SQL 客户端使用

输入输出示例

输入输出说明
CREATE TABLE employees (id NUMBER, name VARCHAR2(100), hire_date DATE);CREATE TABLE employees ( id NUMBER, name VARCHAR2(100), hire_date DATE ); -- 表已创建。常规:最基础的 DDL 建表语句,验证工具能否正确解析并格式化输出。
SELECT ROUND(123.4567, 2) FROM DUAL;123.46常规:常用数值函数 ROUND,验证四舍五入逻辑(第三位 6 进位)。
SELECT DENSE_RANK() OVER (ORDER BY salary DESC) AS rank FROM employees;DENSE_RANK() 返回结果集中各行的排名,排名连续且不跳过(如 1,2,2,3)。 示例输出: RANK ---- 1 2 2 3常规:分析函数 DENSE_RANK 典型用法,验证工具是否提供结果说明而非仅语法。
CREATE TABLE t (id NUMBER(0));CREATE TABLE t ( id NUMBER(0) ); -- 表已创建。但 NUMBER(0) 只能存储 0,实际业务中极少使用。边界:精度为 0 的 NUMBER 类型,工具应提示其业务含义限制。
SELECT TRUNC(99.9999, 0) FROM DUAL;99边界:TRUNC 函数截断而非四舍五入,验证与 ROUND 的区别。99.9999 截断后为 99。
SELECT FIRST_VALUE(salary) OVER (ORDER BY hire_date) FROM employees;FIRST_VALUE 返回窗口内第一行的 salary 值。 示例输出(假设 hire_date 最早为 2020-01-01,salary=5000): FIRST_VALUE ----------- 5000边界:分析函数 FIRST_VALUE 在窗口未指定 ROWS/RANGE 时的默认行为(全窗口),验证工具是否说明默认窗口范围。
ALTER TABLE t ADD (col1 NUMBER, col2 NUMBER);ALTER TABLE t ADD ( col1 NUMBER, col2 NUMBER ); -- 表已修改。注意:ALTER TABLE 添加多列时,列定义需用括号包裹并用逗号分隔。易错:ALTER TABLE ADD 多列的正确语法(括号 + 逗号),新手常误写成 ADD col1 NUMBER, col2 NUMBER(漏括号)。
SELECT NVL(NULL, '默认值') FROM DUAL;默认值易错:NVL 函数处理 NULL 值,但第二个参数类型必须与第一个兼容。若类型不匹配会报错,工具应输出结果并提示类型要求。

常见错误对照

1.DDL 中 VARCHAR2 未指定长度

✗ 错误CREATE TABLE t (name VARCHAR2);
✓ 修复CREATE TABLE t (name VARCHAR2(100));

Oracle 的 VARCHAR2 必须指定长度(字节或字符),否则报 ORA-00906:缺失左括号。这是 SQL 标准与 Oracle 实现的差异。

2.分析函数 OVER() 内 ORDER BY 与 PARTITION BY 顺序颠倒

✗ 错误SELECT ROW_NUMBER() OVER (ORDER BY dept_id PARTITION BY dept_id) FROM emp;
✓ 修复SELECT ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) FROM emp;

Oracle 语法要求 PARTITION BY 必须在 ORDER BY 之前,否则报 ORA-00933:SQL 命令未正确结束。这是解析器顺序依赖。

3.TO_DATE 格式串与输入字符串不匹配

✗ 错误TO_DATE('2024-01-15', 'YYYY/MM/DD')
✓ 修复TO_DATE('2024-01-15', 'YYYY-MM-DD')

TO_DATE 的格式掩码必须精确匹配输入分隔符。'-' 与 '/' 不匹配会报 ORA-01861:文字与格式字符串不匹配。

4.NVL 与 NVL2 参数混淆

✗ 错误NVL2(expr, 'is_null_value')
✓ 修复NVL2(expr, 'not_null', 'is_null')

NVL2 需要三个参数:expr、非空返回值、空返回值。只传两个参数报 ORA-00909:参数个数无效。

5.DECODE 函数中相等比较误用 '=' 而非逗号

✗ 错误DECODE(status = 'A', 'Active', 'Inactive')
✓ 修复DECODE(status, 'A', 'Active', 'Inactive')

DECODE 使用逗号分隔参数对,不是等号表达式。写等号会报 ORA-00920:无效的关系运算符。

6.分析函数 LAG/LEAD 的偏移量参数类型错误

✗ 错误LAG(salary, '2') OVER (ORDER BY hire_date)
✓ 修复LAG(salary, 2) OVER (ORDER BY hire_date)

偏移量必须是数值型,字符串 '2' 会隐式转换失败或报 ORA-01722:无效数字。

7.ALTER TABLE MODIFY 列名后漏写数据类型关键字

✗ 错误ALTER TABLE emp MODIFY salary(10,2);
✓ 修复ALTER TABLE emp MODIFY salary NUMBER(10,2);

MODIFY 子句必须完整写出新数据类型(NUMBER/VARCHAR2/等),仅写精度括号会被解析为语法错误。

8.TRUNC 函数对 DATE 类型省略 fmt 参数导致时间被截断

✗ 错误SELECT TRUNC(SYSDATE) FROM dual; -- 期望保留时分秒
✓ 修复SELECT SYSDATE FROM dual;

TRUNC(date) 默认将时间部分截断到午夜 00:00:00。若需保留时间,不应使用 TRUNC。这是函数语义而非错误。

9.MERGE 语句中 ON 条件使用不等号导致全表扫描

✗ 错误MERGE INTO t1 USING t2 ON (t1.id <> t2.id) WHEN MATCHED THEN UPDATE SET ...
✓ 修复MERGE INTO t1 USING t2 ON (t1.id = t2.id) WHEN NOT MATCHED THEN INSERT ...

MERGE 的 ON 子句设计为等值匹配。使用不等号会使每行都匹配,导致全表更新而非按需操作。

第三节

工作原理

How It Works

核心公式

RANK() OVER (PARTITION BY col1 ORDER BY col2 DESC) AS rk

变量说明

  • col1分区列,分组依据
  • col2排序列,决定顺序
  • rk排名序号,从1开始递增

示例

表 sales 有 dept='IT' 的 3 行:emp='A', amount=500;emp='B', amount=800;emp='C', amount=500。执行 RANK() OVER (PARTITION BY dept ORDER BY amount DESC) 后:B 得 rk=1,A 和 C 并列 rk=2(因 amount 相同,下一名跳过 rk=3)。

SQL 语句输入语法解析(DDL / 函数 / 分析函数)分类索引(建表 / 增删改 / 查询)速查结果示例代码生成
用户输入 本地处理 输出结果
第五节

常见问题

Q & A
这个速查表里的 DDL 语法能直接复制到 PL/SQL Developer 里跑吗?

可以。本工具的 DDL 语法(CREATE TABLE、ALTER TABLE 等)使用标准 Oracle SQL 写法,与 PL/SQL Developer、SQL*Plus 等客户端兼容。但需要注意两点:一是如果你的表空间名、字段名用了中文,建议用双引号括起来;二是约束名(如 PK_EMP)需要保证在当前 schema 下唯一,否则会报 ORA-02260 错误。直接复制前建议先选中执行,不要全选粘贴。

为什么我查的 TO_CHAR 转换日期格式,结果跟预期完全不一样?

最常见的原因是格式模型大小写混用。Oracle 中 TO_CHAR 的格式模型是大小写敏感的:'YYYY' 输出四位年份,'RRRR' 也是四位但规则不同;'MM' 是月份数字,'MON' 是英文月份缩写(如 JAN),'Month' 是带首字母大写的全名(如 January)。另外,如果日期字段本身包含时间,但只用 TO_CHAR(date, 'YYYY-MM-DD') 会截断时间,不会报错但结果只有日期部分。建议对照本工具「日期转换」小节里的常用模板来写。

分析函数(窗口函数)里的 OVER(PARTITION BY) 和 GROUP BY 到底有什么区别?

核心区别:GROUP BY 会压缩行,每个分组只返回一行;而 PARTITION BY 不压缩行,每一行都保留,同时计算出聚合值。例如,统计每个部门的平均工资:用 GROUP BY 只能得到部门 + 平均工资两列,看不到每个员工的具体工资;用 ROUND(AVG(salary)) OVER(PARTITION BY dept_id) 则每一行都显示该员工所属部门的平均工资,方便做“比部门平均高多少”的计算。实际使用时,如果既要明细行又要聚合值,只能用分析函数。

这个工具是离线的吗?我公司内网连不了外网。

是的,本工具完全在浏览器本地运行,没有任何数据上传或后端请求。所有 SQL 语法、示例、说明都打包在页面静态资源中,打开一次后即使断网也能正常使用(前提是浏览器没有清缓存)。适合内网开发环境。如果公司网络限制严格,建议提前在能上网的机器上打开一次,让浏览器缓存完整页面,之后在内网直接访问同一 URL 即可。

我想查某个分析函数的完整语法,但速查表里只有简单示例,没有参数说明怎么办?

本工具的定位是「速查」而非「官方文档」,每个函数只列出最常用的 1-2 种调用形式和典型场景。如果你需要完整的参数列表(例如 LEAD 的 offset 默认值、IGNORE NULLS 子句等),建议结合 Oracle 官方文档(Database SQL Language Reference)或使用 SQL*Plus 的 DESCRIBE 命令查看。速查表更适合你已经知道函数名、但记不清写法时快速确认,不适合零基础从头学。

为什么我写 MERGE INTO 语句时一直报 ORA-30926?

ORA-30926(无法在源表中获得一组稳定的行)通常是因为 MERGE 的 ON 条件在源表(USING 部分)中匹配到多行,导致目标表的一行对应源表多行,Oracle 不知道用哪行来更新。解决办法:确保 USING 子查询中每个 ON 字段组合是唯一的,或者用 ROW_NUMBER() 分析函数先对源数据去重(例如只取最新一条)。本工具的 MERGE 示例默认使用主键作为 ON 条件,就是为了避免此问题。

NVL 和 COALESCE 到底选哪个?性能有差别吗?

功能上,COALESCE 是 NVL 的超集——NVL 只能处理两个参数(expr1, expr2),如果 expr1 为 NULL 则返回 expr2;COALESCE 可以传多个参数,返回第一个非 NULL 值。性能方面,在 Oracle 中两者底层实现几乎一样,没有明显差异。建议优先用 COALESCE,因为更灵活(后续增加备选值不用改函数名),而且 ANSI 标准,迁移到其他数据库时改动更少。如果确定只需要两个参数,用 NVL 也可以,代码更短。

这个速查表里有没有 Oracle 12c 才有的新语法?我还在用 11g。

本工具覆盖的语法以 Oracle 11g R2 和 12c 的主流特性为主,但部分 12c 新增功能(如 TOP-N 查询的 FETCH FIRST 子句、IDENTITY 列、WITH FUNCTION 等)没有包含在内,因为 11g 环境无法使用。如果你在使用 11g,建议避开 FETCH FIRST(改用 ROWNUM 或 ROW_NUMBER())、LATERAL 派生表等 12c 特性。工具页面的每个示例都标注了适用版本的最低要求,可以留意看。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

选择 打开 +新窗口 esc关闭