1
0
mirror of https://github.com/apachecn/lmpythw-zh.git synced 2025-05-28 12:02:19 +00:00
lmpythw-zh/ex41.md
wizardforcel e7a5010454 ex41
2017-08-15 09:49:12 +08:00

87 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 练习 41SQL 更新
> 原文:[Exercise 41: Updating with SQL](https://learncodethehardway.org/more-python-book/ex41.html)
> 译者:[飞龙](https://github.com/wizardforcel)
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻译](https://translate.google.cn/)
现在,你了解了 CRUD 的 CR 部分,还剩下更新和删除操作。与所有其他 SQL 命令一样,`UPDATE`命令遵循类似于`DELETE`的格式,但它会更改行中的列,而不是删除它们。
```sql
UPDATE person SET first_name = "Hilarious Guy"
WHERE first_name = "Zed";
UPDATE pet SET name = "Fancy Pants"
WHERE id=0;
SELECT * FROM person;
SELECT * FROM pet;
```
在上面的代码中,我将我的名字改为`"Hilarious Guy"`,因为这更准确。为了展示我的新绰号,我将我的独角兽更名为`"Fancy Pants"`。他喜欢它。
这不应该很难弄清楚,只是以防万一,我拆解第一个:
+ 以`UPDATE`开始,这是你将要更新的表,这里是`person`
+ 接下来使用`SET`来说明,哪些列应该被设置为什么值。只要你用逗号分隔,如`first_name = "Zed", last_name = "Shaw"`,你可以按需更改尽可能多的列。
+ 然后指定一个`WHERE`子句,为每行提供一个`SELECT`风格的测试集。当`UPDATE`找到匹配时,它执行更新,并会将列`SET`为你规定的样子。
## 复杂表的更新
在上一个练习中,我让你使用`UPDATE`执行子查询,现在我要求你,将所有我拥有的宠物的名称更改为`"Zed's Pet"`
```sql
SELECT * FROM pet;
UPDATE pet SET name = "Zed's Pet" WHERE id IN (
SELECT pet.id
FROM pet, person_pet, person
WHERE
person.id = person_pet.person_id AND
pet.id = person_pet.pet_id AND
person.first_name = "Zed"
);
SELECT * FROM pet;
```
这是根据另一个表的信息更新一个表的方法。还有其他一些方法,可以做同样的事情,但是这样做是最容易理解。
## 更新数据
我将向你展示一种插入数据的替代方式有助于原子地替换一行。你不一定经常需要它但是如果必须替换整个记录并且不希望在不使用事务的情况下执行更复杂的UPDATE那么它将会有所帮助。
这里,我想用另一个人替换我的记录,但仅仅保留 ID。问题是我必须在事务中执行`DELETE/INSERT`才能使其成为原子,否则我需要执行一个完整的`UPDATE`
另一个更简单的方法是使用`REPLACE`命令,或者将其添加到`INSERT`作为修饰符。这里有一些 SQL我首先无法插入新的记录然后我使用这两种形式的`REPLACE`来实现它:
```sql
/* This should fail because 0 is already taken. */
INSERT INTO person (id, first_name, last_name, age)
VALUES (0, 'Frank', 'Smith', 100);
/* We can force it by doing an INSERT OR REPLACE. */
INSERT OR REPLACE INTO person (id, first_name, last_name, age)
VALUES (0, 'Frank', 'Smith', 100);
SELECT * FROM person;
/* And shorthand for that is just REPLACE. */
REPLACE INTO person (id, first_name, last_name, age)
VALUES (0, 'Zed', 'Shaw', 37);
/* Now you can see I'm back. */
SELECT * FROM person;
```
## 挑战练习
+ 使用`UPDATE`,通过我的`person.id`,将我的名字改回`"Zed"`
+ 写一个`UPDATE`,将任何死亡动物重命名为`"DECEASED"`。如果你尝试说他们是`"DEAD"`,它会失败,因为 SQL 会认为你的意思是,将其设置为名为`"DEAD"`的列,这不是你想要的。
+ 尝试使用一个子查询,比如在`DELETE`中。
+ 访问 [SQL As Understood By SQLite](http://www.sqlite.org/lang.html) 页面,并开始阅读`CREATE TABLE``DROP TABLE``INSERT``DELETE``SELECT``UPDATE`的文档。
+ 尝试在这些文档中找到一些有趣的事情,并记录你不明白的事情,以便你可以稍后研究它们。