How to manage huge number of UPDATE statements in SQL Server - sql-server-2008

I just executed more number of update statements(500) in SQL Server like below
update di_artikel
set beschaffungszeit_intern = '14'
where nr = '0.600.910.0L09631'
update di_artikel
set beschaffungszeit_intern = '14'
where nr = '0.600.910.1L09631'
update di_artikel
set beschaffungszeit_intern = '14'
where nr = '0.600.910.2L09631'
update di_artikel
set beschaffungszeit_intern = '14'
where nr = '0.600.910.4L09631'
update di_artikel
set beschaffungszeit_intern = '14'
where nr = '0.600.910.5L09631'
update di_artikel
set beschaffungszeit_intern = '14'
where nr = '0.600.910.8L09631' ...... more
I got the result like
(1 row(s) affected) or
(0 row(s) affected).
0 rows means some materials(nr) are not executed.
Reason for that is some materials in not in di_artikel table.
BUT I NEED TO FIND UN SUCCESSFUL MATERIALS, HOW I NEED TO GET?

with cte
as
(
select
* from table where nr in ('keep all your inputs')
)
update cte
output inserted.*
set nr ='whatever value'
inserted.* gives you only what is updated value,which helps you in understanding which rows are updated

Related

How can I perform this MySql Statement in a loop

I would write my cmd line statements more sophistically. How can this be done by using a loop?
update refs set custom_7 = '';
update refs set custom_7='1' where custom_7 = '' limit 220 ;
update refs set custom_7='2' where custom_7 = '' limit 220 ;
update refs set custom_7='3' where custom_7 = '' limit 220 ;
...
update refs set custom_7='100' where custom_7 = '' limit 220 ;
thanks a lot.
If there is a column, like an id, that defines the order of the rows by which you want to update the rows, use ROW_NUMBER() window function to rank the rows and join to the table:
WITH cte AS (SELECT *, ROW_NUMBER() OVER (ORDER BY id) rn FROM refs)
UPDATE refs r
INNER JOIN cte c ON c.id = r.id
SET r.custom_7 = (c.rn - 1) DIV 220 + 1
WHERE c.rn <= 100 * 220; -- remove the WHERE clause if there is actually no limit to the values of custom_7
If there is no column like the id, you may remove ORDER BY id from the OVER() clause of ROW_NUMBER(), but then the rows will be updated arbitrarily.
See a simplified demo.
You can try something like this (please replace datatype(length) with the type of custom7)
DECLARE #count INT;
SET #count = 1;
WHILE #count<= 100
BEGIN
UPDATE refs SET custom_7 = CAST(#count AS **datatype(length)**) WHERE custom_7 = '' LIMIT 220;
SET #count = #count + 1;
END;

Problem with increment variable and stored procedure to check duplicates

I have problem with my procedure. I have table oferty_in which contain fields (id, status, ..., id_om). I want procedure which check if exist rows with the same id_om.
If exist, delete rows where status = 'N' (N - new).
My procedure almost works, but i have problem with iterate in loop. Every time I run my procedure ,procedure delete a half of rows. I don't know where is problem...
DELIMITER //
CREATE PROCEDURE check_duplicates_oferty_in()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE v_id_del BIGINT;
SELECT count(*) INTO n FROM oferty_in where status_oferty = 'N';
SET i=0;
WHILE i<n DO
IF EXISTS (SELECT id_om FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1) THEN
SELECT id_om INTO v_id_del FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1;
DELETE from oferty_in where id_om = v_id_del and status_oferty = 'N';
END IF;
SET i=i+1;
END WHILE;
END
//
I try also:
IF EXISTS (SELECT id_om FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1) THEN
SELECT id_om INTO v_id_del FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1;
DELETE from oferty_in where id_om = v_id_del and status_oferty = 'N';
SET i=i+1;
ELSE
SET i=i+1;
END IF;
But it's the same.
Every time half of rows. I use counter 'i' and while loop to iterate row by row on rows in oferty_in when status = 'N'. Anyone have a idea what I did wrong? Thanks for help and time.
You seem to want to delete rows with status = 'N' when id_om is duplicated.
I want procedure which check if exist rows with the same id_om. If exist, delete rows where status = 'N' (N - new).
Non-working code doesn't generally help explain logic, so this is what I am going by.
You definitely do not need a looping construct for this, nor a cursor:
delete o
from oferty_in o join
(select o2.id_om
from oferty_in o2
group by o2.id_om
having count(*) > 1 and sum(status = 'N') > 0
) o2
on o.id_om = o2.id_om
where o.status = 'N';

How to 2 UPDATE in One MySQL Query

in MySQL query
How to do 2 UPDATE in one Query, the query below:
UPDATE `stats` SET `coin` = coin + 500 WHERE `player` = 'userone'
UPDATE `stats` SET `coin` = coin - 500 WHERE `player` = 'usertwo'
You can use case and in:
UPDATE `stats`
SET `coin` = coin + (case when player = 'userone' then 500 else -500 end)
WHERE `player` in ( 'userone', 'usertwo');
UPDATE stats
SET coin = CASE player
WHEN 'userone' THEN coin + 500
WHEN 'usertwo' THEN coin - 500
END
WHERE player IN ('userone', 'usertwo')

MySQL Count values in a column, Update and replace value which has a limit amount

I have a problem with a MySQL Update statement.
I have more than 100.000 Entries in the table. So my approaches were not successful. (see below)
First, I want to count the number of values (thats easy):
SELECT values1 ,count(values1) FROM table
GROUP BY value1
HAVING COUNT(value1) <= 1000;
Second, i want to replace some values of the column values1 which appears only <= 1000 times.
So I tried these statement:
Update table as t
SET t.value1 = "limitAmount"
WHERE EXISTS (select value1 from
(select * from table) as f Group by f.value1
Having count(f.value1) <= 1000);
When i tried this SQL statement, i received:
Error Code 1205. Lock Wait timeout exceeded. Try restarting transaction.
Try this
Update
table as t
SET
t.value1 = "limitAmount"
WHERE
EXISTS (select value1 from (select * from table) as f where f.value1 = t.value1 Group by f.value1 Having count(f.value1) <= 1000);
Notice where f.value1 = t.value1 condition in the subquery
This statement works:
UPDATE test SET val="BLUB"
WHERE val IN
(SELECT val FROM (SELECT val FROM test GROUP BY val HAVING COUNT(val) <2000) war);
alternative:
Adding Values to a separate table
INSERT INTO helpTable (Value1) (select val FROM test
Group by val
Having count(val) <= 2000);
Select
Update test as t
SET t.val = "BLUB"
WHERE NOT EXISTS (Select Value1 FROM helpTable as h WHERE t.val = h.Value1);

Update multiple rows from same table in mysql

Update a single column over multiple rows depending on the data from the same table.
update table1 set status=newtime
from (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
where id2='2'
and status='0'
)
where id=new_id
This is my query. Thanks in advance.
Edit:
This is an alternate query to achieve this. But it also gives me an error
update table1 set status=
(select
case when timeleft<0 then '4' else '0' end as something,
new_id
from
(
select
TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss') as newtime,
id as new_id
FROM
table1
where id2='2' and
status='0'
)
}
where id=new_id
"#1248 - Every derived table must have its own alias".
I cannot use alias as I am fetching two columns from the query. Any help would be great.
UPDATE statements have no FROM clause in MySQL syntax. However, you can JOIN table against the subquery.
UPDATE
table1 t1
JOIN (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
WHERE id2='2' AND status='0'
) tsub ON t1.id = tsub.new_id
SET status = tsub.newtime
It looks to me like you don't need to do any subquerying or joining at all. This should do what you want:
UPDATE table1
SET status = CASE WHEN TIME_FORMAT(TIMEDIFF(ADDTIME(time_val, '120:00:00'), NOW()), '%Hh %im %ss') < 0 THEN '4' ELSE '0' END
WHERE id2 = '2' AND status = '0'
In the query you wrote, your subquery will get back the new time_val and the id number of the row to update, for any rows that match the criteria id2 = '2' AND status = '0'. You will then update all those rows (that matched the above criteria) and set the status to the new time_val.
Instead of selecting them first, cut out the middle man and just update all rows that match that criteria with the new value. Your query will be faster and more straightforward.
Besides the simplified version (provided by #Travesty3), it seems you are using a whole bunch of date and time functions to test for a simple thing:
UPDATE table1
SET status = '4'
WHERE id2 = '2'
AND status = '0'
AND time_val < NOW() - INTERVAL 120 HOUR
We can update table with multiple row by same table or two different table in this manner, just posting a snippet of mysql code from my procedure
Update documentcolumns as tb1, documentcolumns as tb2 set tb1.documentColumnPos = tb2.documentColumnPos Where tb1.userID = user_id and tb2.userID is NULL and tb1.columnNameDefID= tb2.columnNameDefID and tb1.tabtype = tab_type and tb2.tabtype = tab_type;,