首页 > 解决方案 > 如何通过存储过程更新表的多行?

问题描述

将这张表的图像作为我需要执行多个更新操作的表我有一个包含 1000 个条目的员工表,另一个表是包含 1000 个条目的部门表。我创建了一个映射表,其中包含两个表的主键,它也有 1000 个条目。现在,我必须加入所有这三个表并对某些行执行更新过程,但它应该能够一次性更新行,这也是使用存储过程的首选。需要一些帮助!

我知道使用 table 变量来执行此操作,但我需要了解如何编写脚本来创建存储过程并执行相同操作。

谢谢。

标签: sqlsql-serverdatabasejoininner-join

解决方案


正如许多人在评论中所建议的那样,您绝对应该阅读UPDATESQL Server 中的工作原理,因为这将完成您所需要的一切。

无论如何,这里有一个示例可以帮助您解释这一点。首先,让我们创建一个表Employees并用一些记录填充它:

create table Employees
(
    id int,
    first_name varchar(50),
    last_name varchar(50),
    starting_date date,
    last_checked date
)

insert into Employees values 
(1, 'John', 'Smith', '2016-05-16', null),
(2, 'Sandra', 'Evans', '2013-02-02', null),
(3, 'Phil', 'Jones', '2019-10-25', null),
(4, 'Jenny', 'Lewis', '2018-07-11', null),
(5, 'Steve', 'Daniels', '2018-02-28', null)

现在我们可以选择该表中的所有行并查看数据:

select * from Employees

RESULTS:
/------------------------------------------------------------\
| id | first_name | last_name | starting_date | last_checked |
|----|------------|-----------|---------------|--------------|
| 1  | John       | Smith     | 2016-05-16    | NULL         |
| 2  | Sandra     | Evans     | 2013-02-02    | NULL         |
| 3  | Phil       | Jones     | 2019-10-25    | NULL         |
| 4  | Jenny      | Lewis     | 2018-07-11    | NULL         |
| 5  | Steve      | Daniels   | 2018-02-28    | NULL         |
\------------------------------------------------------------/

现在,如果我们想更新表中的每一行,例如在last_checked列中设置一个值,这可以通过一个简单的UPDATE语句来完成:

update Employees set last_checked = getdate()

这会更新表中的每条记录:

select * from Employees

RESULTS:
/------------------------------------------------------------\
| id | first_name | last_name | starting_date | last_checked |
|----|------------|-----------|---------------|--------------|
| 1  | John       | Smith     | 2016-05-16    | 2020-01-21   |
| 2  | Sandra     | Evans     | 2013-02-02    | 2020-01-21   |
| 3  | Phil       | Jones     | 2019-10-25    | 2020-01-21   |
| 4  | Jenny      | Lewis     | 2018-07-11    | 2020-01-21   |
| 5  | Steve      | Daniels   | 2018-02-28    | 2020-01-21   |
\------------------------------------------------------------/

如果需要,您同样可以使用WHERE子句来确定应该更新哪些记录:

update Employees set last_checked = '2019-01-01' where starting_date <= '2019-01-01'

select * from Employees

RESULTS:
/------------------------------------------------------------\
| id | first_name | last_name | starting_date | last_checked |
|----|------------|-----------|---------------|--------------|
| 1  | John       | Smith     | 2016-05-16    | 2019-01-01   |
| 2  | Sandra     | Evans     | 2013-02-02    | 2019-01-01   |
| 3  | Phil       | Jones     | 2019-10-25    | 2020-01-21   |
| 4  | Jenny      | Lewis     | 2018-07-11    | 2019-01-01   |
| 5  | Steve      | Daniels   | 2018-02-28    | 2019-01-01   |
\------------------------------------------------------------/

请注意,last_checked除了 Phil Jones 的日期之外,每个日期都是如何更新的,因为声明中的where starting_date <= 2019-01-01条款update

希望这演示了update语句的基础知识,如果您需要,当然可以将其包装在存储过程中:

create procedure [dbo].[updateEmployeeLastChecked] 
    @newDate date = null
as

if @newDate is null set @newDate = getdate()
update Employees set last_checked = @newDate where starting_date <= @newDate

因此,在这种情况下,存储过程采用一个可选参数(如果未提供,则默认为当前日期)指定更新Employees表中记录时要使用的日期,前提是指定的日期在starting_date每个员工之后。不是一个特别有用或现实的程序,但它很有希望地展示了这一原则。


推荐阅读