43

I have a question regarding the following syntax. Is there a cleaner way to roll this up into one statement rather than two. I've tried several iterations but this seems to be the only way I can successfully execute these two statements.

UPDATE employee
SET hire_date = '1979-03-15'
WHERE emp_id = 'PMA42628M' 

UPDATE employee
SET hire_date = '1988-12-22'
where emp_id = 'PSA89086M'; 

I tried this as well and I also tried using an AND statement. Neither worked. Basically I am looking for a less newbie way then the method above, if one exists. I spent a long time searching and did not find one.

UPDATE employee
SET hire_date = ('1979-03-15', '1988-12-22')
WHERE emp_id = ('PMA42628M', 'PSA89086M');

Appriciate any advice on this one, and by the way, I am using sql server. Thanks

Devart
  • 119,203
  • 23
  • 166
  • 186
user2454335
  • 431
  • 1
  • 4
  • 3

4 Answers4

51

Try this one, this will combine multiple selects and returns them as if they come from the DB:

UPDATE e
SET hire_date = t.hire_date
FROM dbo.employee e
JOIN (
    SELECT emp_id = 'PMA42628M', hire_date = '1979-03-15'
    UNION ALL
    SELECT emp_id = 'PSA89086M', hire_date = '1988-12-22'
) t ON t.emp_id = e.emp_id

If you are using SQL Server 2008 or later version, you could also use a different syntax for the derived table:

UPDATE e
SET hire_date = t.hire_date
FROM dbo.employee e
JOIN (
    VALUES
        ('PMA42628M', '1979-03-15'),
        ('PSA89086M', '1988-12-22')
) t (emp_id, hire_date) ON t.emp_id = e.emp_id
Andriy M
  • 76,112
  • 17
  • 94
  • 154
Devart
  • 119,203
  • 23
  • 166
  • 186
15

I am looking for a less newbie way

Doing two separate update statements is (according to me) "the less newbie way" you could complicate stuff and do something like this.

update employee
set hire_date = case emp_id
                  when 'PMA42628M' then '1979-03-15'
                  when 'PSA89086M' then '1988-12-22'
                end
where emp_id in ('PMA42628M', 'PSA89086M')

but what would that gain you? The entire update would run in one implicit transaction so if you want your two updates to be in a transaction you just use begin transaction .... commit.

Mikael Eriksson
  • 136,425
  • 22
  • 210
  • 281
  • 4
    I ended up on this question because I was googling for a way to optimize a slow (interactive) application that does about 100K update statements over the course of a minute. Switching to a combined variant like suggested gave us about 700% speedup so we now do the same work in less than ten seconds. Putting it all in a transcation doesn't help because it's the dispatch and roundtrip time for all the SQL statements that takes up the majority of the time. – flodin Feb 07 '14 at 11:00
  • In my query my `WHERE id IN (...)` is gnarly, so this is a much neater way than two `UPDATE`s. – BrianHenryIE Jun 01 '23 at 21:47
12

You can make a temporary table or a table variable containing the updates you want to do, then run the UPDATE statement linking the table to the table you intend to update.

Note that for two updates, you get two statements: the INSERT into the update table and the UPDATE statement itself. The number of statements remains two though for as many updates you need to do.

CREATE TABLE #employee (emp_id VARCHAR(9) NOT NULL PRIMARY KEY,hire_date DATE NOT NULL);
INSERT INTO #employee (emp_id,hire_date)
VALUES ('PMA42628M','2013-06-05'),('PSA89086M','2013-06-05');

CREATE TABLE #target_updates(emp_id VARCHAR(9) NOT NULL,hire_date DATE NOT NULL);
INSERT INTO #target_updates (emp_id,hire_date)
VALUES ('PMA42628M','1979-03-15'),('PSA89086M','1988-12-22');
UPDATE
    #employee
SET
    hire_date=tu.hire_date
FROM
    #employee AS e
    INNER JOIN #target_updates AS tu ON
        tu.emp_id=e.emp_id;

SELECT
    *
FROM
    #employee
ORDER BY
    emp_id;
DROP TABLE #target_updates;
DROP TABLE #employee;
TT.
  • 15,774
  • 6
  • 47
  • 88
  • 4
    This shd be the accepted answer as its applicable to updating n number of rows from a table that already exists as well – Rashmi Pandit Oct 17 '16 at 01:13
-2

update table_name set='value' where orgid in (idnum1, idnum2)

A.Goutam
  • 3,422
  • 9
  • 42
  • 90