PL/SQL 使用一张表中的列数据更新表,基于不同表之间的相等性
Posted
技术标签:
【中文标题】PL/SQL 使用一张表中的列数据更新表,基于不同表之间的相等性【英文标题】:PL/SQL Update table using column data from one table, based on equality between different tables 【发布时间】:2015-06-11 22:21:16 【问题描述】:基本上,我有 2 个表:EMPLOYEES、DBPZIP。
我需要根据两个语句使用 DBPZIP 中的 ZIP 列更新表 EMPLOYEES 中的 ZIP 列:
EMPLOYEES LOCATION 必须相等,DBPZIP LOCATION 和 DBPZIP DEPARTMENT 必须是 'Store'
到目前为止,我尝试了两种方法:
create or replace PROCEDURE insertZip IS
BEGIN
UPDATE EMPLOYEES
SET EMPLOYEES.ZIP = ( SELECT DPBZIP.POSTCODE
FROM DPBZIP
WHERE DPBZIP.DEPARTMENT = 'Store')
WHERE DPBZIP.LOCATION = EMPLOYEES.LOCATION;
END;
第二种方式:
create or replace PROCEDURE insertZip IS
UPDATE EMPLOYEES
SET EMPLOYEES.ZIP = ( SELECT DPBZIP.POSTCODE
FROM DPBZIP
WHERE DPBZIP.DEPARTMENT = 'Store'
AND DPBZIP.LOCATION = EMPLOYEES.LOCATION);
END;
当我将两个 DBPZIP 都放在 select 语句中时,我得到单行子查询返回多行。
如果我把一个放在外面,我会得到无效的标识符。
【问题讨论】:
此链接将帮助您psoug.org/reference/update.html(请参阅基于返回多个值的查询和相关更新的更新) 您的“第二种方式”只需要额外的更新条件:UPDATE .. WHERE DPBZIP.LOCATION = EMPLOYEES.LOCATION; 首先,编写一个查询,其中包含要更改的数据和要更改的值。可以在此处找到将其更改为更新语句的过程:***.com/questions/28182852/… 【参考方案1】:我不确定为什么您的过程中有 COMMIT
语句。如果您只更新一行,这对我来说并不是一个特别好的主意。其次,除了@Kamil 指出的问题之外,您的查询还有另一个问题;即使您限制子查询返回的行数,只要DBZIP
中没有对应于department
和location
的值的记录,EMPLOYEES.zip
将设置为NULL
。在这种情况下也许这是可以接受的,但我会重写查询如下。
UPDATE employees e
SET e.zip = ( SELECT MAX(d.postcode) FROM dpbzip d
WHERE d.department = 'Store'
AND d.location = e.location )
WHERE EXISTS ( SELECT 1 FROM dpbzip d
WHERE d.department = 'Store'
AND d.location = e.location );
注意我在上面使用了表别名,所以我不必一遍又一遍地输入表名。另请注意,我使用聚合(在本例中为MAX()
)来确保在子查询中只返回一行。 (WHERE EXISTS
子句中的子查询可以返回多行没有问题。)
【讨论】:
【参考方案2】:第一种方式: 它在语法上不正确,因为 UPDATE 语句的范围内不存在 EMPLOYEES 别名。
第二种方式: 您得到单行子查询返回多行,因为在 SQL 语句中使用“=”您需要等式右侧的一个值。假设一个位置 (DBZIP.LOCATION) 只返回一个 (DBZIP.POSTCODE),您可以通过添加谓词 ROWNUM = 1 或在 select 子句中添加 DISTINCT 来限制返回的行数。
【讨论】:
以上是关于PL/SQL 使用一张表中的列数据更新表,基于不同表之间的相等性的主要内容,如果未能解决你的问题,请参考以下文章
循环遍历一张表中的列值并将另一列中的 COUNTIF 值粘贴到另一张表中