pgsql更新操作

6.2. 更新数据

修改已经存储在数据库中的数据的行为叫做更新。你可以更新 独立的行,也可以更新表中所有的行,还可以更新其中的一部分行。 我们可以独立地更新每个字段,而其他的字段则不受影响。

要执行一次更新,你需要三种信息:

  1. 表的名字和要更新的字段名,

  2. 字段的新数值,

  3. 要更新的是哪行。

我们在 Chapter 5 里说过,SQL 通常并不为数据行提供唯一标识。 因此我们无法直接声明需要更新哪一行。但是, 我们可以通过声明一个要更新的行必须满足的条件。 只有在表里面存在主键的时候(不管你叫它什么),我们才能可靠地指定一个独立的行, 方法是选取一个匹配主键的行。图形化的数据库访问工具依赖这个东西来让我们可以独立地更新某些行。

比如,这条命令更新价格为5的所有产品的的价格为10:

UPDATE products SET price = 10 WHERE price = 5;

这样做可能导致零行,一行或者更多数据行被更新。 如果我们试图做一个不匹配任何数据行的更新,那也不算错误。

让我们仔细看看这个命令。首先是关键字 UPDATE, 然后跟着表名字。和平常一样,表名字也可以是用模式修饰的, 否则就会从路径中把它找出来。然后是关键字 SET, 后面跟着字段名,一个等号以及新的字段数值。新的字段数值可以是任意标量表达式, 而不仅仅是常量。比如,如果你想把所有产品的价格提高 10%,你可以用:

UPDATE products SET price = price * 1.10;

如你所见,用于新值的表达式也可以引用行中现有的数值。我们还忽略了 WHERE 子句。如果我们忽略了这个子句, 那么就意味着表中的所有行都要更新。如果出现了WHERE 子句, 那么只有匹配它后面的条件的行被更新。请注意在 SET 子句中的等号是一个赋值, 而在 WHERE 子句中的等号是比较,不过这样并不会导致任何歧义。 当然条件 WHERE 不一定非得是相等测试。 许多其他操作符也都可以使用(参阅 Chapter 9)。 但是表达式必须得出一个布尔结果。

你还可以在一个 UPDATE 命令中更新更多的字段, 方法是在 SET 子句中列出更多赋值。比如:

UPDATE mytable SET a = 5, b = 3, c = 1 WHERE a > 0;

### 更新 PostgreSQL 序列的方法 在 PostgreSQL 中,可以通过 `SETVAL` 函数来手动设置序列的当前。此函数允许指定一个新的作为序列的当前位置,并可以选择是否将其视为已使用的下一个。 以下是更新序列的具体方法: #### 使用 SETVAL 函数 `SETVAL` 是用于修改序列当前的核心函数。它接受两个参数:第一个是序列名称,第二个是要设置的新。第三个可选布尔参数表示是否将新标记为已使用过的[^1]。 语法如下: ```sql SELECT setval('sequence_name', new_value, is_called); ``` - **sequence_name**: 要更新的序列名。 - **new_value**: 设置为新的当前。 - **is_called**: 布尔,默认为 `false`。如果设为 `true`,则意味着该已经被取出过;如果是 `false`,那么下次调用 `NEXTVAL` 将返回这个而不是跳到下一个。 #### 示例代码 假设有一个名为 `my_sequence` 的序列,希望将其重置为 100 并确保下一次调用 `NEXTVAL` 返回的是 101,则可以这样操作: ```sql -- 不标记为已使用状态 SELECT setval('my_sequence', 100); -- 或者标记为已使用状态 SELECT setval('my_sequence', 100, true); ``` #### 自动调整序列以匹配表中的最大 ID 当向数据库中插入数据时可能绕过了默认的序列机制(比如批量导入),这可能导致序列不再同步于实际的最大主键。为了修复这种情况,通常会重新初始化序列使其等于对应字段的最大加一。 下面是一个通用脚本用来自动修正某个特定表及其关联序列的关系: ```sql DO $$ DECLARE max_id INTEGER; BEGIN -- 获取目标表 id 列的最大 SELECT COALESCE(MAX(id), 0) INTO max_id FROM my_table; -- 设定 sequence 至上述计算所得数之上一位 PERFORM setval('my_table_id_seq', max_id + 1); END $$; ``` 这里需要注意替换 `'my_table'` 和 `'my_table_id_seq'` 成真实的表格名字以及相应的序列名称[^2]。 ### 注意事项 尽管可以直接操纵序列,但在高并发环境下这样做可能会引发竞争条件或者违反业务逻辑约束等问题。因此,在设计应用程序的时候应该尽量依赖内置功能而非频繁干预底层实现细节。 问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值