SQL Update Multiple Rows with Multiple Values - sql

I have a list of items that I need to update based on their unique ID in a SQL Server 2005 environment. I was wondering what the best way of writing a script to update these items.
I know I can simply update a column by writing multiple queries such as:
UPDATE myTable
SET HelpLink = 'newLink'
WHERE ID = 5
UPDATE myTable
SET HelpLink = 'newLink2'
WHERE ID = 6
Is there any other way of doing this without having to repeat the above update about 20 times? Repeating the above tends to make a pretty ugly update script.
NOTE: I have a bulk set of items that I will be updating by their unique ID, these items are not coming from a database table.

I found out that you can use case statements which seems to simplify things quite a bit. This allows me to add multiple items into a single query.
UPDATE [MyTable]
SET HelpLink = CASE ID
WHEN 2 THEN 'MKSDefectsChart.png'
WHEN 6 THEN 'EPMRisks.png'
WHEN 7 THEN 'DCTSHardwareChanges.png'
ELSE NULL
END
WHERE ID IN (2, 6, 7)

You can always update from another table like
update myTable
set HelpLink = myOtherTable.HelpLink
from myOtherTable
where myTable.[ID] = myOtherTable.[ID]
You'll have to create that other table though

Related

Update date parameter in multiple table using SQL

I need to update the below dates for multiple records in a table. Each record has a unique Id call object_id. I have used the below SQL to update one record but would like to know if I can bulk update them. I constantly receive these requests to update the date. This time it is only 6 records but usually, I get the request to update even 50 records.
This is the data that I received
This is the data in the database table.
I need to update the CASE_DETAIL table by adding the judgment date into JUDGMENT_DATE COLUMN which is currently null.
update case_detail cd set CD.JUDGMENT_DATE = '18/DEC/1998' where CD.OBJECT_ID = 5091449
Any advice in the direction of creating a SQL script that would bulk update the date column in multiple records would be of great assistance.
If your new values are arriving in a table, you can update the case_detail table by doing:
update case_detail cd
set judgment_date = (select r.judgement_date
from received r
where cd.object_id = r.object_id
)
where exists (select 1
from received r
where cd.object_id = r.object_id
);
Please try this.
UPDATE case_detail cd SET CD.JUDGMENT_DATE = '18/DEC/1998' WHERE CD.OBJECT_ID IN (SELECT OBJECT_ID FROM #ReceivetableName) AND CD.JUDGMENT_DATE IS NULL

simple UPDATE query on large table has bad performance

I need to do the following update query through a stored procedure:
UPDATE table1
SET name = #name (this is the stored procedure inputparameter)
WHERE name IS NULL
Table1 has no indexes or keys, 5 columns which are 4 integers and 1 varchar (updatable column 'name' is the varchar column)
The NULL records are about 15.000.000 rows that need updating. This takes about 50 minutes, which I think is too long.
I'm running an Azure SQL DB Standard S6 (400DTU's).
Can anyone give me an advise to improve performance?
As you don't have any keys, or indexes, I can suggest following approach.
1- Create a new table using INTO (which will copy the data) like following query.
SELECT
CASE
WHEN NAME IS NULL THEN #name
ELSE NAME
END AS NAME,
<other columns >
INTO dbo.newtable
FROM table1
2- Drop the old table
drop table table1
3- Rename the new table to table1
exec sp_rename 'dbo.newtable', 'table1'
Another approach can be using batch update, sometime you get better performance compared to bulk update (You need to test by adjusting the batch size).
WHILE EXISTS (SELECT 1 FROM table1 WHERE name is null)
BEGIN
UPDATE TOP (10000) table1
SET name = #name
WHERE n ame is null
END
can you do with following method ?
UPDATE table1
SET name = ISNULL(name,#name)
for null values it will update with #name and rest will be updated with same value.
No. You are updating 15,000,000 rows which is going to take a long time. Each update has overhead for finding the row and logging the value.
With so many rows to update, it is unlikely that the overhead is finding the rows. If you add an index on name, the update is going to actually have to update the index as well as updating the original values.
If your concern is locking the database, you can set up a loop where you do something like this over and over:
UPDATE TOP (100000) table1
SET name = #name (this is the stored procedure inputparameter)
WHERE name IS NULL;
100,000 rows should be about 30 seconds or so.
In this case, an index on name does help. Otherwise, each iteration of the loop would in essence be reading the entire table.

SQL Trigger not working upon update

I have the following code (in sql server - via 2012): i can't seem to get it right. any suggestions.
Table:
select top 1000 [supplier],
[item],
[reorder_level],
[current_inventory],
[reorder],
from [clinic].[dbo].[emr_suppliers]
I'm working on a trigger and a bit stuck.
CREATE TRIGGER reorder_supplies
ON emr_suppliers
After insert, update
As BEGIN
update emr_suppliers
set reorder = 'yes'
where (emr_suppliers.reorder = emr_suppliers.current_inventory or emr_suppliers.reorder > emr_suppliers.current_inventory)
update emr_suppliers
set reorder = 'no'
where emr_suppliers.reorder < emr_suppliers.current_inventory
END
What the trigger has to do is compare the Current Inventory with the Reorder Level column, and if the value of the Current Inventory is equal to or less than the Reorder Level, it will put a value of Yes in the Reorder column, and if it is not, then it will put a No value instead.
The trigger itself looks syntactically correct.
However, I don't think it's a solution with a decent performance since each and every row of the emr_suppliers table is touched twice, even though there was no data change at all for most of the rows (e.g. after insert of a new row or update of a single value).
I'd use a solution based on the internal inserted table together with a CASE expression:
UPDATE emr_suppliers
SET reorder =
CASE WHEN emr_suppliers.reorder < emr_suppliers.current_inventory THEN 'no'
WHEN emr_suppliers.reorder >= emr_suppliers.current_inventory THEN 'yes'
ELSE reorder -- don't change the value
END
FROM emr_suppliers INNER JOIN inserted ON emr_suppliers.primary_key = inserted.primary_key

select the rows affected by an update

If I have a table with this fields:
int:id_account
int:session
string:password
Now for a login statement I run this sql UPDATE command:
UPDATE tbl_name
SET session = session + 1
WHERE id_account = 17 AND password = 'apple'
Then I check if a row was affected, and if one indeed was affected I know that the password was correct.
Next what I want to do is retrieve all the info of this affected row so I'll have the rest of the fields info.
I can use a simple SELECT statement but I'm sure I'm missing something here, there must be a neater way you gurus know, and going to tell me about (:
Besides it bothered me since the first login sql statement I ever written.
Is there any performance-wise way to combine a SELECT into an UPDATE if the UPDATE did update a row?
Or am I better leaving it simple with two statements? Atomicity isn't needed, so I might better stay away from table locks for example, no?
You should use the same WHERE statement for SELECT. It will return the modified rows, because your UPDATE did not change any columns used for lookup:
UPDATE tbl_name
SET session = session + 1
WHERE id_account = 17 AND password = 'apple';
SELECT *
FROM tbl_name
WHERE id_account = 17 AND password = 'apple';
An advice: never store passwords as plain text! Use a hash function, like this:
MD5('apple')
There is ROW_COUNT() (do read about details in the docs).
Following up by SQL is ok and simple (which is always good), but it might unnecessary stress the system.
This won't work for statements such as...
Update Table
Set Value = 'Something Else'
Where Value is Null
Select Value From Table
Where Value is Null
You would have changed the value with the update and would be unable to recover the affected records unless you stored them beforehand.
Select * Into #TempTable
From Table
Where Value is Null
Update Table
Set Value = 'Something Else'
Where Value is Null
Select Value, UniqueValue
From #TempTable TT
Join Table T
TT.UniqueValue = T.UniqueValue
If you're lucky, you may be able to join the temp table's records to a unique field within Table to verify the update. This is just one small example of why it is important to enumerate records.
You can get the effected rows by just using ##RowCount..
select top (Select ##RowCount) * from YourTable order by 1 desc

How to update multiple rows in the same table of MySQL with PHP?

If only one row with a distinct field is to be updated,I can use:
insert into tab(..) value(..) on duplicate key update ...
But now it's not the case,I need to update 4 rows inside the same table,which have its field "accountId" equal to $_SESSION['accountId'].
What I can get out of my mind at the moment is:
delete from tab where accountId = $_SESSION['accountId'],
then insert the new rows.
Which obviously is not the best solution.
Has someone a better idea about this?
Use the update just like that!
update tab set col1 = 'value' where accountId = $_SESSION['accountId']
Moreover, MySQL allows you to do an update with a join, if that makes your life a bit easier:
update
tab t
inner join accounts a on
t.accountid = a.accountid
set
t.col1 = 'value'
where
a.accountname = 'Tom'
Based on your question, it seems like you should review the Update Statement.
Insert is used to put new rows in - not update them. Delete is used to remove. And Update is used to modify existing rows. Using "Insert On Duplicate Key Update" is a hackish way to modify rows, and is poor form to use when you know the row is already there.
load all of the values in to a temporary table.
UPDATE all of the values using a JOIN.
INSERT all of the values from the temp table that don't exist in the target table.
You can use replace statement. This will work as a DELETE followed by INSERT