MySQL Trigger duplicate data - mysql

i had query like this
CREATE TRIGGER `tambah_riwayatobat` AFTER INSERT ON `obat`
FOR EACH ROW insert into riwayat_obat(nama, keterangan, distributor,tanggal)
(select new.nama, 'Masuk', d.nama ,now()
From distributor d
join obat ON new.id_distributor = d.id_distributor)
i try to insert data with trigger and one of part data i fetch with constraint, but why the data be duplicate entry ?
Output :
example, if i try to insert data obat 1st time, data on tambah_riwayatobat insert 1 too
if i try to insert data obat 2nd time, data on tambah_riwayatobat insert 2 times with same data
if i try to insert data obat 3rd time, data on tambah_riwayatobat insert 3 times with same data

I'm not certain exactly what's happening, but it's a result of the join in your trigger code. You’re joining obat to distributor, but your join condition makes no mention of obat so you're getting some sort of cross-product where on the second and subsequent INSERT your SELECT subquery is selecting more than one row.
You shouldn't (and don't need to) use the join, since all the data you need from obat is already in the pseudorecord NEW. The following code should work much better:
CREATE TRIGGER `tambah_riwayatobat`
AFTER INSERT ON `obat`
FOR EACH ROW
INSERT INTO riwayat_obat
(nama, keterangan, distributor, tanggal)
(SELECT NEW.nama, 'Masuk', d.nama, now()
FROM distributor d
WHERE new.id_distributor = d.id_distributor
LIMIT 1);
The LIMIT clause will ensure that the SELECT selects only one row, so the INSERT inserts only one row; if distributor.id_distributor is a primary key the LIMIT clause is unnecessary.

Related

Updating column on one table with values from another table

I'm trying to update an empty table notes, with values that come from a column in another table deals:
UPDATE notes
SET notes.content = (
SELECT deals.memo
FROM deals
WHERE deals.id = notes.deal_id
);
this runs with no error but no notes get updated although there are loads of values in memo.
There's no values at all in notes. Can this be the problem?
Perhaps you want to insert rows into notes:
INSERT INTO notes (deal_id, content)
SELECT d.id, d.ememo
FROM deals;
This will add rows into notes with values from the rows in deals.

mysql insert...select statement causing deadlock in concurrent request

MySQL version 5.7
Engine : InnoDB
I have table called "md_waiting_slot_count" and it has following columns:
cell | popupDate | userId | creationTime
Now I have following query:
insert into md_waiting_slot_count
select cell, '2017-08-31' as pd, 'abnc' as ui, '2017-08-26 15:55:51'
from
(select sum(slotcount) as tt, cell from
( select 0 as slotcount, cell_str as cell, 'master' from cell where
cell_str in
("Gujarat_Jamnagar_Jamnagar_00-18_Male","Gujarat_Jamnagar_Jamnagar_19-
22_Male")
union all
select slotcount, cell, wting from
(select count(*) as slotcount, cell as cell, 'waiting' as wting from
md_waiting_slot_count where
cell in(SELECT cell_str as cell FROM cell where cell_str
in("Gujarat_Jamnagar_Jamnagar_00-18_Male","Gujarat_Jamnagar_Jamnagar_19-
22_Male"))
and popupDate='2017-08-31' and creationTime > DATE_SUB(NOW(), INTERVAL
20 MINUTE) group by cell ) as t1
union all
select filledslotcount as slotcount, id as cell, 'final' from
md_slot_count where id in(
SELECT cell_str as cell FROM cell where cell_str
in("Gujarat_Jamnagar_Jamnagar_00-18_Male","Gujarat_Jamnagar_Jamnagar_19-
22_Male"))
and popupSlotDate='2017-08-31' ) t group by cell having tt < 4) as ft
order by cell, pd, ui
on duplicate key update creationTime = "'2017-08-26 15:55:51'";
Here 2 other table also used which are as follow
md_slot_count
id| popupDate| state| district| taluka| ageGroup| gender| filledSlotCount
cell
cell_str| state| district| taluka| ageGroup| gender
This insert...select statement causing deadlock after 3-4 successful run.
Help me with this.
How to see "last deadlock log" in MySQL?
I want to do something like this
Transaction 1 --> evaluate above query --> insert row
Transaction 2 --> evaluate above query --> insert row
Here when second transaction evaluate query it has to consider the data inserted by previous transaction. Here I want to allow max 4 transaction to insert row, no more than that. So the evaluated query allow to insert then only insert.
Now in parallel request if those 2 process of query evaluation and insertion is separate and no consider previous transaction data, then more then 4 transaction can come and insert data.
So the ultimate goal is to
If one transaction begin and read data and fulfil the condition then insert data and mean while no one else make insertion, and as the first transaction complete, the second transaction has to consider all the updated data only. So either complete or nothing for one transaction and other transaction has to wait. I do not achieve in concurrent request, as all read together and so it read old data so all are able to add data in table.
So I take this whole in one single query.
You want to insert into md_waiting_slot_count some data calculated from md_waiting_slot_count.
So deadlock is unavoidable. Try to create a temporary table containing your values and then insert your values from your temporary table.

MySQL insert in one of two tables based on condition for one table

Consider two tables that have timestamp and data columns. I need to construct an SQL that does the following:
Insert data (unique timestamp and data column) in one table if timestamp value is not present in the table ("insert my data in table 1 for timestamp="12:00 1999-01-01" only if that timestamp is not present in table 1...)
Otherwise, insert very same data in different table without any checks, and overwrite if necessary (... otherwise insert same set of fields in table 2).
How I could possibly achieve this on SQL? I could do it using a client but this is way slower. I use MySQL
Run a query for your 2nd bullet first. i.e. insert data into table 2 if it is present in table 1
insert into table2 (data, timestamp)
select 'myData', '12:00 1999-01-01'
from table1
where exists (
select 1 from table1
where timestamp = '12:00 1999-01-01'
)
limit 1
Then run your the query for your 1st bullet i.e. insert into table1 only if the data doesn't already exist
insert into table1 (data, timestamp)
select 'myData', '12:00 1999-01-01'
from table1
where not exists (
select 1 from table1
where timestamp = '12:00 1999-01-01'
)
limit 1
Running both these queries will always only insert 1 row into 1 table because if the row exists in table1, the not exists condition of the 2nd query will be false and if it doesn't exist in table1, then the exists condition of the 1st query will be false.
You may want to consider creating a unique constraint on table1 to automatically prevent duplicates so you can use insert ignore for your inserts into table1
alter table table1 add constraint myIndex (timestamp);
insert ignore into table1 (data,timestamp) values ('myData','12:00 1999-01-01');
A regural INSERT statement can insert records into one table only. You have 2 options:
Code the logic within the application
Create a stored procedure within mysql and code the application logic there
No matter which route you choose, I would
Add a unique index on the timestamp column in both tables.
Attempt to insert the data into the 1st table. If the insert succeeds, everything is OK. If the timestamp exists, then you will get an error (or a warning depending on mysql confioguration). Your solution handles the error (in mysql see DECLARE ... HANDLER ...).
Insert the data into the 2nd table using INSERT INTO ... ON DUPLICATE KEY UPDATE ... statement, which will insert the data if the timestamp does not exists, or updates the record if it does.

TRIGGER INSERT last row into one of the chosen tables if WHERE conditions are true

I am currentlty using triggers in a table to copy the last row into a designated table based on a WHERE condition and ORDER BY. Using one trigger works fine and copies to the respective table. but both triggers are running causing duplicates of a previous row to appear in the table I dont want inserted. (SQL2008 Management Studio). I have specific tables to send this row too based on the partnumber. Here is the Structure:
ALTER TRIGGER NewT3650 ON JD_Passdata
FOR INSERT
AS
INSERT T3_650_TestData (SerialNumber, Partnumber, etc)
SELECT TOP 1 SerialNumber, Partnumber, etc
FROM JD_Passdata
WHERE partnumber = 'T3_650'
ORDER BY passdata_ndx DESC
ALTER TRIGGER NewT4450 ON JD_Passdata
FOR INSERT
AS
INSERT T4_450_TestData (SerialNumber, Partnumber, etc)
SELECT TOP 1 SerialNumber, Partnumber, etc
FROM JD_Passdata
WHERE partnumber = 'T4_450'
ORDER BY passdata_ndx DESC
Original PassData Table:
201244999, T4_450
201245001, T3_650
201245002, T3_650
201245003, T3_650
Returns Results for table 1
201245001, T3_650
201245002, T3_650
201245003, T3_650
Returns Results for table 2
201244999, T4_450
201244999, T4_450
201244999, T4_450
I would like this to be an OR condition or a UNION that only takes the last row and enters it into the correct table and remove the additional trigger if possible. Otherwise a check for duplicate and update may do it too. Also the database is going to get quite large to do a DESC every entry may get slow. A method to remove the order by would be a consideration as well.
Any sugesstions would be greatly appreciated...THX
I have a solution that works for both triggers but may be causing a problem when a "NULL" result occurs. It does get rid of the ORDER BY and may be faster. What this does is use the unique last row index number as the row location and checks the part number to determine an insert into the new table. Also, when I add a third trigger using this same format for a different table the initial move to the main table (JD_PassData) fails. Not sure why yet.
Here is the new code:
ALTER TRIGGER NewT3650 ON JD_Passdata
AFTER INSERT
AS
INSERT T3_650_TestData (SerialNumber, Partnumber, etc)
SELECT SerialNumber, Partnumber, etc
FROM JD_Passdata
WHERE passdata_ndx=(SELECT MAX(passdata_ndx) FROM JD_PassData) AND PartNumber = 'T3_650'

how to insert without duplicate from one table into another

I tried to insert from one table into another and im having with the redundancy..
I came up with a query but every time when i execute it, It cannot deals with duplicate.
here's my query...
INSERT INTO balik ( balik_date, balik_time, balik_cardID, balik_status,balik_type)
select current_date(), '00:00:00', L_CardID, 'BELUM BALIK', L_Type
FROM logdetail t1
LEFT JOIN balik t2 ON (t1.L_CardID = t2.balik_cardID)
WHERE t1.L_Type = 'IN'
any help will be greatly appreciated
Use INSERT IGNORE instant of INSERT.
Use INSERT IGNORE rather than INSERT. If a record doesn't duplicate an
existing record, MySQL inserts it as usual. If the record is a
duplicate, the IGNORE keyword tells MySQL to discard it silently
without generating an error.
OR
Check row count for unique field. If row exist don't insert or update.
OR
Use REPLACE rather than INSERT. If the record is new, it's inserted
just as with INSERT. If it's a duplicate, the new record replaces the
old one:
Source for definitions MySQL Handling Duplicates