SQL

SQL（ˈ或ˈ，Structured Query Language，结构化查询语言）是一种特定目的程式语言，用于管理关系数据库管理系统（RDBMS），或在关系流数据管理系统（RDSMS）中进行流处理。

20 世纪 70 年代推出的 SQL 相比早期的读写 API（如 ISAM 或 VSAM）具有两大优势：首先，引入了用一条命令访问多条记录的概念；其次，也消除了指定如何访问记录的需求（即无论是否使用索引）。

SQL最初基于关系代数和元组关系演算，包含多种类型的语句，这些语句可被非正式地归类为以下子语言：数据查询语言（DQL）；数据定义语言（DDL）；数据控制语言（DCL）；数据操作语言（DML）。

SQL 的应用范围涵盖了数据查询、数据操作（插入、更新和删除）、数据定义（模式创建与修改）以及数据访问控制。尽管 SQL 本质上是一种声明式语言（第四代语言），但是也包含了过程式元素。

SQL 是最早采用埃德加・F・科德提出的关系模型的商用语言之一。该模型在他 1970 年发表的具有重大影响力的论文《大型共享数据库的关系数据模型》中被详细阐述。尽管 SQL 并未完全遵循科德所描述的关系模型，但还仍然成为了使用最为广泛的数据库语言。

SQL在1986年成为美国国家标准学会（ANSI）的一项标准，在1987年成为国际标准化组织（ISO）标准。此后，这一标准经过了一系列的增订，加入了大量新特性。虽然有这一标准的存在，但大部分的SQL代码在不同的数据库系统中并不具有完全的跨平台性。

## 历史

在1970年代初，由IBM研究院下属爱曼登研究中心的埃德加·科德发表将资料组成表格的应用原则（Codd's Relational Algebra）。1974年，同一实验室的唐纳德·钱柏林和雷蒙德·博伊斯参考了科德的模型后，在研制关系数据库管理系统中，开发出了一套规范语言SEQUEL（Structured English Query Language，结构化英语查询语言），并在1976年11月的《IBM研究与开发杂志》上公布新版本的SQL（叫SEQUEL/2）。1980年改名为SQL。

1979年，甲骨文公司（当时名为关系式软件公司）首先提供商用的SQL，IBM公司在DB2和SQL/DS数据库系统中也实现了SQL。

1986年10月，美国ANSI采用SQL作为关系数据库管理系统的标准语言（ANSI X3. 135-1986），后为国际标准化组织（ISO）采纳为国际标准。

1989年，美国ANSI采纳在ANSI X3.135-1989报告中定义的关系数据库管理系统的SQL标准语言，称为ANSI SQL 89，该标准替代ANSI X3.135-1986版本。该标准为下列组织所采纳：

- 国际标准化组织，为ISO 9075-1989报告《Database Language SQL With Integrity Enhancement》
- 美国联邦政府，发布在《The Federal Information Processing Standard Publication(FIPS PUB)127》

目前，所有主要的关系数据库管理系统支持某些形式的SQL，大部分数据库至少遵守ANSI SQL89标准。

ANSI SQL92标准在交叉连接（cross join）和内部连接之上，新增加了外部连接，并支持在FROM子句中写连接表达式。支持集合的并运算、交运算。支持Case (SQL)表达式。支持CHECK约束。创建临时表。支持cursor。支持事务隔离。

## 语法

<image>

SQL语言分成了几种要素，包括：

- 子句，是语句和查询的组成成分。（在某些情况下，这些都是可选的。）
- 表达式，可以产生任何标量值，或由列和行组成的数据库表
- 谓词，给需要评估的SQL三值逻辑（3VL）（true/false/unknown）或布尔真值指定条件，并限制语句和查询的效果，或改变程序流程。
- 查询，基于特定条件检索数据。这是SQL的一个重要组成部分。
- 语句，可以持久地影响纲要和数据，也可以控制数据库事务、程序流程、连接、会话或诊断。
- SQL语句也包括分号（";"）语句终结符。尽管并不是每个平台都必需，但是由作为SQL语法的标准部分定义的。
- 无意义的空白在SQL语句和查询中一般会被忽略，更容易格式化SQL代码便于阅读。

## 语言特点

SQL是高级的非过程化编程语言，允许用户在高层数据结构上工作。不要求用户指定对数据的存放方法，也不需要用户了解其具体的数据存放方式。而且界面，能使具有底层结构完全不同的数据库系统和不同数据库之间，使用相同的SQL作为数据的输入与管理。由以记录项目〔records〕的合集（set）〔项集，record set〕作为操纵对象，所有SQL语句接受项集作为输入，回送出的项集作为输出，这种项集特性允许一条SQL语句的输出作为另一条SQL语句的输入，所以SQL语句可以嵌套，这使得拥有极大的灵活性和强大的功能。在多数情况下，在其他编程语言中需要用一大段程序才可实践的一个单独事件，而其在SQL上只需要一个语句就可以被表达出来。这也意味着用SQL可以写出非常复杂的语句，在不特别考虑效能下。

SQL同时也是数据库文件格式的扩展名。

SQL包含四个部分：

- 资料定义语言
- 资料操纵语言
- 资料控制语言
- 事务控制语言

### SQL函数

函数｜描述

AVG｜平均值

COUNT｜计数（不含Null）

FIRST｜第一个记录的值

MAX｜最大值

MIN｜最小值

STDEV｜样本标准差

STDEVP｜总体标准差

SUM｜求和

VAR｜样本方差

VARP｜总体方差

UCASE｜转化为全大写字母

LCASE｜转化为全小写字母

MID｜取中值

LEN｜计算字符串长度

INSTR｜获得子字符串在母字符串的起始位置

取字符串左边子串取字符串右边子串

ROUND｜数值四舍五入取整

MOD｜取余

NOW｜获得当前时间的值

FORMAT｜字符串格式化

DATEDIFF｜获得两个时间的差值

## 互操作性和标准化

供应商之间的SQL实现不兼容，不一定完全遵循标准。各种数据库的SQL方言通常不可移植，特别是在日期时间语法、字符串连接、`NULL`、比较的大小写敏感方面。只有PostgreSQL与Mimer SQL努力遵从标准。

### 标准化历史

SQL在1986年被ANSI标准化，1987年被ISO标准化。由ISO/IEC JTC 1/SC 32维护。标准名称通常为如下模式：ISO/IEC 9075-n:yyyy Part n: title。

年份｜名字｜别名｜注释

1986｜SQL-86｜SQL-87｜ANSI首次标准化

1989｜SQL-89｜FIPS 127-1｜小修改，增加了integrity constraint

1992｜SQL-92｜SQL2, FIPS 127-2｜大修改，成为现代SQL的基础

1999｜SQL:1999｜SQL3｜增加了正则表达式匹配、递归查询（传递闭包）、数据库触发器、过程式与控制流语句、非标量类型(arrays)、面向对象特性。在Java中嵌入SQL(SQL/OLB)及其逆(SQL/JRT)

2003｜SQL:2003｜增加XML相关特性(SQL/XML)、window functions、标准化sequences、自动产生值的列。对SQL:1999的新特性重新描述其内涵。

2006｜SQL:2006｜导入/导出XML数据与SQL数据库。XQuery

2008｜SQL:2008｜在cursor之外的ORDER BY语句。INSTEAD OF触发器。TRUNCATE语句。FETCH子句

2011｜SQL:2011｜增加时态数据(PERIOD FOR)。增强了window functions与FETCH子句

2016｜SQL:2016｜增加行模式匹配、多态表函数、JSON。

2019｜SQL:2019｜增加了第15部分，多维数组（MDarray类型和运算符）。

### 当前标准

该标准通常用以下模式表示：ISO/IEC 9075-n：yyyy 第n部分：标题，或者简称为ISO/IEC 9075。

ISO / IEC 9075补充了ISO / IEC 13249：SQL多媒体和应用程序包（SQL/MM），该程序包定义了基于SQL的接口和包，给诸如视频，音频和空间数据之类的广泛的应用程序。感兴趣的各方可以从ISO、IEC或ANSI购买SQL标准文档。SQL：2008的草稿可作为zip存档免费获得。

#### SQL标准剖析

SQL标准包含10部分：

- ISO/IEC 9075-1:2016 Part 1: Framework (SQL/Framework). 提供逻辑概念
- ISO/IEC 9075-2:2016 Part 2: Foundation (SQL/Foundation). 包含语言的主要内容，强制与可选特性。
- ISO/IEC 9075-3:2016 Part 3: Call-Level Interface (SQL/CLI). 定义了接口成分(structures, procedures, variable bindings) 用于编写能执行SQL的应用程序的语言：Ada，C/C++，COBOL，Fortran，MUMPS，Pascal，PL/I。对于Java语言见标准第10部分。ODBC是一个著名的SQL/CLI的超集。这部分标准主要包含强制的特性。
- ISO/IEC 9075-4:2016 Part 4: Persistent stored modules (SQL/PSM)。SQL的过程式扩展，包括控制流、条件处理、语句条件signals与resignals、cursors、本地变量、表达式赋值到变量与参数。此外，SQL/PSM形式化声明与维护了持续性（persistent）数据库语言例程（例如存储过程）。这部分标准主要包含可选的特性。
- Part-6: Support for JavaScript Object Notation (JSON). 2017年首次集成JSON数据类型到SQL标准。
- ISO/IEC 9075-9:2016 Part 9: Management of External Data (SQL/MED). 这部分标准主要包含可选的特性。
- ISO/IEC 9075-10:2016 Part 10: Object language bindings (SQL/OLB)。定义了SQLJ，SQL嵌入到Java，保证了SQLJ应用程序二进制可移植。这部分标准主要包含可选的特性。
- ISO/IEC 9075-11:2016 Part 11: Information and definition schemas (SQL/Schemata). 定义了Information Schema与Definition Schema，提供了常用工具集使得SQL数据库与对象自描述。这些工具包括SQL object identifier、structure与integrity constraints、security与authorization specifications, features与packages。这部分标准主要包含强制与可选的特性。
- ISO/IEC 9075-13:2016 Part 13: SQL Routines and types using the Java TM programming language (SQL/JRT). SQL应用程序调用静态方法作为子程序的能力('Java-in-the-database')；Java类作为SQL结构化用户定义类型。这部分标准主要包含可选的特性。
- ISO/IEC 9075-14:2016 Part 14: XML-Related Specifications (SQL/XML). 这部分标准主要包含可选的特性。
- ISO/IEC 9075-15:2019 Part 15: 多维数组(SQL/MDA)，是为SQL指定了多维数组类型（MDarray），以及对MDarray，MDarray切片，MDarray单元和相关功能的操作。标准的这一部分仅包含可选功能。

#### ISO / IEC标准的扩展

ISO/IEC 9075被ISO/IEC 13249: SQL Multimedia and Application Packages (SQL/MM)补充。后者定义了基于SQL的音视频、空间数据的界面与包。包括：

- ISO/IEC 13249-1:2016 Part 1: Framework
- ISO/IEC 13249-2:2003 Part 2: Full-Text
- ISO/IEC 13249-3:2016 Part 3: Spatial
- ISO/IEC 13249-5:2003 Part 5: Still image
- ISO/IEC 13249-6:2006 Part 6: Data mining
- ISO/IEC 13249-7:2013 Part 7: History
- ISO/IEC 13249-8:xxxx Part 8: Metadata Registry Access MRA (work in progress)

## 以SQL为基础的其他延伸语言

- Transact-SQL

微软MS SQL-Server，以及系列数据库所用的SQL

- PL-SQL

Oracle 数据库所使用的SQL

## 安全问题

由于SQL指令在部分进阶使用时，语法会依照特定条件来变换，而且若是表格中的字段过多时，许多开发人员都会习惯以字串组立的方式建立SQL指令，而且又使用系统管理员级的账户连到数据库，因此让骇客有机会利用SQL的组立方式进行攻击，像是在指令中添加部分刺探性或破坏性的指令（例如`DROP TABLE`、`DROP DATABASE`或是`DELETE * FROM myTable`等具破坏性的指令），让数据库的资料或实体服务器被破坏，导致服务中断或是系统瘫痪等后果，或是以逻辑的漏洞，在密码栏写入特殊字串(例如' or '1'='1)，让该字串形成的逻辑判断永远为真，或直接取得非查询条件的资料，而不需要知道密码，以达成非法登入系统的目的，此种攻击手法称为SQL注入（SQL injection）。

目前实务上较有效的防御方法，就是全面改用参数化查询。

## 外部链接

- Comparison of different SQL implementations

## 基本资料

- 日语原文：结构化查询语言
- 编程范型：声明式
- 语言家族：查询语言
- 发行时间：1974
- 设计者：唐纳德·钱柏林、雷蒙德·博伊斯
- 开发者：国际标准化组织/国际电工委员会
- 类型系统：类型系统, 强型别
- dialects：SQL-86, SQL-89, SQL-92
- 受影响于：Datalog
- 施影响于：语言集成查询, , Windows PowerShell, , 面向Java对象查询
- 操作系统：跨平台
- wikibooks：Structured Query Language
- 日语原文：SQL（文件格式）
- 扩展名：.sql
- mime：application/sql
- 所有者：ISO/IEC
- 发行日期：1986年
- 最新版本：2016年
- 类型：Database
- 标准：ISO/IEC 9075
- 免费在线档案：Yes