跳转到内容

结构化查询语言/处理数据

来自维基教科书,开放世界中的开放书籍


如上一页所示,我们现在有一个名为 person 的空表。我们能用这样的表格做什么?就像使用一个袋子一样!将东西存放在里面,查看里面的东西是否存在,修改里面的东西,或者将东西从里面拿出来。这些是与表格中的数据相关的四个基本操作。

  • INSERT:将一些数据放入表中
  • SELECT:从表中检索数据
  • UPDATE:修改表中存在的数据
  • DELETE:从表中删除数据。

对于这四个操作中的每一个,都有一个 SQL 命令。它以一个关键字开头,并以一个分号结束。此规则适用于所有 SQL 命令:它们以一个关键字开头,并以一个分号结束。在中间,可能还有更多关键字,以及对象名称和值。

使用 INSERT 命令存储新数据

[编辑 | 编辑源代码]

当将新数据存储在表的行中时,我们必须命名所有受影响的对象和值:表名(数据库中可能有很多表)、列名和值。所有这些都嵌入在一些关键字中,以便 SQL 编译器可以识别标记及其含义。通常,简单 INSERT 的语法如下:

INSERT INTO <tablename> (<list_of_columnnames>)
VALUES                  (<list_of_values>);


以下是一个示例

-- put one row
INSERT INTO person (id, firstname, lastname,    date_of_birth,     place_of_birth, ssn,           weight)
VALUES             (1,  'Larry',   'Goldstein', date'1970-11-20', 'Dallas',        '078-05-1120', 95);
-- confirm the INSERT command
COMMIT;

当 DBMS 识别 INSERT INTO 和 VALUES 关键字时,它就知道该做什么:它在表中创建一行,并将给定的值放入命名的列中。在上面的示例中,命令后跟第二个命令:COMMIT 确认 INSERT 操作以及其他写入操作 UPDATE 和 DELETE。(我们将在后面的章节中详细了解 COMMIT 及其对应命令 ROLLBACK。)

关于 date_of_birth 值格式的简短说明:世界各地没有通用的日期格式。人们根据自己的文化习惯使用不同的格式。为了我们的目的,我们决定使用 ISO 8601 中定义的分层格式来表示日期。可能您的本地数据库安装使用不同的格式,因此您被迫修改我们的示例或修改数据库安装的默认日期格式。

现在我们将更多行放入我们的表格中。为此,我们使用上述语法的变体。如果值列表与原始 CREATE TABLE 语句中使用的列数、顺序和数据类型完全匹配,则可以省略列名列表。

提示:不建议在实际应用程序中省略列名列表!表结构会随着时间的推移而发生变化,例如有人可能会向表中添加新列。在这种情况下,应用程序可能会出现意外的副作用。
-- put four rows
INSERT INTO person VALUES (2,  'Tom',    'Burton',    date'1980-01-22', 'Birmingham',    '078-05-1121', 75);
INSERT INTO person VALUES (3,  'Lisa',   'Hamilton',  date'1975-12-30', 'Mumbai',        '078-05-1122', 56);
INSERT INTO person VALUES (4,  'Debora', 'Patterson', date'2011-06-01', 'Shanghai',      '078-05-1123', 11);
INSERT INTO person VALUES (5,  'James',  'de Winter', date'1975-12-23', 'San Francisco', '078-05-1124', 75);
COMMIT;

使用 SELECT 命令检索数据

[编辑 | 编辑源代码]

现在我们的表格应该包含五行。我们能确定吗?如何检查所有操作是否都正常进行,并且行和值确实存在?为此,我们需要一个命令来显示表格的实际内容。它是 SELECT 命令,其通用语法如下

SELECT   <list_of_columnnames>
FROM     <tablename>
WHERE    <search_condition>
ORDER BY <order_by_clause>;


与 INSERT 命令一样,您可以省略某些部分。最简单的示例是

SELECT   *
FROM     person;

星号 '*' 表示“所有列”。在结果中,DBMS 应该提供所有五行,每行包含之前使用 INSERT 命令的七个值。

在以下示例中,我们将逐一添加通用语法中当前缺失的子句。


添加一些或所有列名的列表

SELECT   firstname, lastname
FROM     person;

DBMS 应该提供所有五行的 firstnamelastname 两列。


添加搜索条件

SELECT   id, firstname, lastname
FROM     person
WHERE    id > 2;

DBMS 应该提供三行的 idfirstnamelastname 三列。


添加排序说明

SELECT   id, firstname, lastname, date_of_birth
FROM     person
WHERE    id > 2
ORDER BY date_of_birth;

DBMS 应该按 date_of_birth 升序提供三行的 idfirstnamelastnamedate_of_birth 四列。

使用 UPDATE 命令修改数据

[编辑 | 编辑源代码]

如果我们想更改某些行中某些列的值,可以使用 UPDATE 命令。简单 UPDATE 的通用语法如下

UPDATE <tablename>
SET    <columnname> = <value>, 
       <columnname> = <value>,
                   ...
WHERE  <search_condition>;

值为命名的列赋值。未提及的列保持不变。search_condition 的作用与 SELECT 命令相同。它将命令的覆盖范围限制为满足条件的行。如果省略 WHERE 关键字和 search_condition,则会影响表的所有行。可以指定不匹配任何行的 search_condition。在这种情况下,不会更新任何行,并且不会出现任何错误或异常。

更改一行的一列

UPDATE person
SET    firstname = 'James Walker' 
WHERE  id = 5;
COMMIT;

Mr. de Winter 的名字更改为 James Walker,而他的所有其他值保持不变。此外,所有其他行保持不变。请使用 SELECT 命令验证这一点。

更改多行的一列

UPDATE person
SET    firstname = 'Unknown' 
WHERE  date_of_birth < date'2000-01-01';
COMMIT;

<search_condition> 不限于主键列。我们可以指定任何其他列。比较运算符也不限于等于号。我们可以使用不同的运算符,它们只需要与列的数据类型匹配。

在此示例中,我们使用单个命令更改了四行的 firstname。如果一个表有数百万行,我们可以使用一个命令更改所有行。


更改一行两列

-- Please note the additional comma
UPDATE person
SET    firstname = 'Jimmy Walker', 
       lastname  = 'de la Crux' 
WHERE  id = 5;
COMMIT;

两个值使用一个命令更改。

使用 DELETE 命令删除数据

[编辑 | 编辑源代码]

DELETE 命令从表中删除完整行。由于行是整体删除的,因此无需指定任何列名。<search_condition> 的语义与 SELECT 和 UPDATE 相同。

DELETE
FROM   <tablename>
WHERE  <search_condition>;


删除一行

DELETE
FROM   person
WHERE  id = 5;
COMMIT;

James de Winter 的行从表中删除。


删除多行

DELETE
FROM   person;
COMMIT;

由于我们省略了 <search_condition>,因此所有剩余的行都被删除。该表为空,但仍然存在。


没有受影响的行

DELETE
FROM   person
WHERE  id = 99;
COMMIT;

此命令将不会删除任何行,因为没有 id 等于 99 的行。但是,语法和 DBMS 中的执行仍然是完美的。不会抛出异常。命令在没有任何错误消息或错误代码的情况下终止。

INSERT 和 DELETE 命令会影响整个行。INSERT 将一个完整的新行放入表中(未提及的列保持为空),DELETE 删除整个行。相反,SELECT 和 UPDATE 只影响命令中提到的列;未提及的列不受影响。

INSERT 命令(在此页面的简单版本中)没有 <search_condition>,因此仅处理一行。其他三个命令可能会影响零行、一行或多行,具体取决于其 <search_condition> 的评估结果。


华夏公益教科书