Trigger on MySQL tables with variable? - mysql

I need to create in MySQL trigger on such schema:
mail
oid id
varchar name
varchar reference
adress_mail
oid id
oid id_mail
oid id_adress
adress
oid id
varchar name
after something is inserted into adress_mail it is updating 'mail.reference' with value like every 'adress.name' for example:
I am inserting adress_mail with (1,5,6) and (1,5,7) so trigger will update 'mail.reference' with values from 'adress.name where adress.id = 6' and 'adress.name where adress.id = 7'
Q: The whole problem is how to loop on adress_mail table and get all
'adress.name' in 1 varchar and then just update 'mail.reference' with
that value?
I can setup something like var (variable) in trigger and then collect all results from select?
PS 'mail.reference' it's varchar row to improve some searching feature of application, because I don't have possibility to loop on 'adress_mail' table.

Just don't do that ! You are using an sql data base, and the main idea of it is table relations, so when you'll have to look for data from address linked to mail, perform a select with joins on address_mail.

Related

Replace string in column value MYSQL

Hi i have a table named data_table with columns ID | DATA
Id is integer and Data stored like this:
a:19:{s:10:"store_name";s:9:"STORENAME";s:6:"social";a:7:{s:2:"fb";s:0:"";s:7:"twitter";s:0:"";s:9:"pinterest";s:0:"";s:8:"linkedin";s:0:"";s:7:"youtube";s:0:"";s:9:"instagram";s:0:"";s:6:"flickr";s:0:"";}s:7:"payment";a:2:{s:6:"paypal";a:1:{i:0;s:5:"email";}s:4:"bank";a:0:{}}s:5:"phone";s:0:"";s:10:"show_email";s:2:"no";s:7:"address";a:6:{s:8:"street_1";s:0:"";s:8:"street_2";s:0:"";s:4:"city";s:0:"";s:3:"zip";s:0:"";s:7:"country";s:0:"";s:5:"state";s:0:"";}s:8:"location";s:0:"";s:6:"banner";i:0;s:4:"icon";i:0;s:8:"gravatar";i:0;s:14:"show_more_ptab";s:3:"yes";s:9:"store_ppp";i:12;s:10:"enable_tnc";s:3:"off";s:9:"store_tnc";s:0:"";s:23:"show_min_order_discount";s:2:"no";s:9:"store_seo";a:0:{}s:24:"dokan_store_time_enabled";s:2:"no";s:23:"dokan_store_open_notice";s:0:"";s:24:"dokan_store_close_notice";s:0:"";}
Also i have another table named user_stores ID | STORE
Id is integer and store is string format.
I want to make trigger on update when table user_stores change some store name then change the a s:9:"STORENAME
s:9 is the length of the value, in our example is STORENAME
Assuming you're using MySQL, you can create a trigger on the user_stores table to update the data_table when a store name changes. Here's an example:
CREATE TRIGGER update_storename_trigger
AFTER UPDATE ON user_stores
FOR EACH ROW
BEGIN
UPDATE data_table
SET DATA = REPLACE(DATA, CONCAT('s:', LENGTH(OLD.STORE), ':"', OLD.STORE, '"'), CONCAT('s:', LENGTH(NEW.STORE), ':"', NEW.STORE, '"'))
WHERE DATA LIKE CONCAT('%s:', LENGTH(OLD.STORE), ':"', OLD.STORE, '";%');
END;
This trigger will be executed after the user_stores table is updated and will update the DATA column of the data_table if the store name has changed. The REPLACE function is used to replace the old store name with the new store name in the serialized data stored in the DATA column. The WHERE clause is used to search the data table rows that contain the previous store name in the serialized data.
Note that this trigger assumes that the serialized data in the DATA column is in the serialized format. If the data is in a different format, the trigger will have to be modified.
The final answer who works is:
BEGIN
UPDATE data_table as b
SET b.DATA = CONCAT(SUBSTRING_INDEX(b.STORE, 'store_name', 1),'store_name\";s:',LENGTH(new.STORE),':\"',new.STORE,'\";s',SUBSTRING_INDEX(b.STORE, SUBSTRING_INDEX((SUBSTRING_INDEX(b.STORE, 'store_name', -1)), ':',3), -1))
WHERE b.ID=new.ID
END;

mysql insert into table select from another database

I have a table named user in database named client. user has the structure as follows:
`fkey`(varchar(100)) | `status`(enum('1','0'))
I have another database named employees with a table named employee
It has a cloumn named emailid which has all the data I need.
I want all the emailid column data from employees.employee to be inserted in client.user at fkey column.there is another column status in client.user which needs to be set as 1 .How do I create a query for this.
This is my query but it is wrong.
insert into client.user (`fkey`,`status`) select `emailid` from employees.employee,'1';
Definitely it’s wrong syntax . It should be
Insert into client.user (fkey,status) select `emailid`, '1' from employees.employee

Select information from multiple tables with unique ID in the table name

Here is the scenario: I have tables stored in my monitoring application database using IDs as part of the table name. For instance, for 10 monitored devices, the device logs are stored in tables for each device with the device ID as part of the name, like this:
Device ID Table Name
1 device_logs.log_1
2 device_logs.log_2
I want to be able to :
select * from all device log tables where ID IN (a-list-of-IDs)
I reference this type of information a lot, and it would be easier to do it in a quick query and possibly a report. For some small list of devices, a union query works, but after about 4-5 devices, that gets too long. Programmatically, I can do this in python with string substitution, but how do you do it in MySQL as a query?
Adding a code segment I am trying to get to work, but struggling with the syntax:
drop table if exists tmp_logs;
create temporary table tmp_logs
(
device_name varchar(30) not null,
date datetime,
message varchar (255)
)
engine=innodb;
drop procedure if exists load_tmp_log_data;
delimiter #
create procedure load_tmp_log_data()
begin
declare vid int unsigned;
truncate table tmp_logs;
start transaction;
while vid in(4976,4956) do
insert into tmp_logs values
( SELECT
dev.device,
date,
message
FROM device_logs.logs_vid
inner join master_dev.legend_device dev on dev.id=vid
where date >= '2014-7-1'
and message not like '%HDMI%'
and message not like '%DVI%'
and message not like '%SIP%'
and message not like '%Completed%'
and message not like '%Template%'
and message not like '%collection%'
and message not like '%Cache%'
and message not like '%Disconnect%'
and message not like '%Row removed%'
and message not like '%detailed discovery%'
and message not like '%restarted%'
and message not like '%Auto Answer%'
);
end while;
commit;
end #
delimiter ;
call load_tmp_log_data();
select * from tmp_logs order by device_name;
You cannot dynamically specify the user name as a query in regular SQL. You could use a prepare statement with dynamic SQL.
An alternative is to set up the query as:
select l.*
from ((select l.*
from device_logs.log_1 l
where device_id = 1 and id in (list of ids)
) union all
(select l.*
from device_logs.log_2 l
where device_id = 2 and id in (list of ids)
) . . .
) l;
You need to repeat the conditions in each subquery -- that makes them more efficient. And, use union all instead of union to avoid duplication.
Fundamentally, though, having tables of the same structure is often a sign of poor database design. It would be much better to have a single table with a column specifying the id. Then your query would be really easy:
select l.*
from logs l
where id in (list of ids);
You could generate such a table by changing the application that creates the tables. Or you could generate such a table by using an insert trigger on each of the subtables. Or, if the data can be a day or so out of date, run a job that re-creates the table every night.

how can i modify or manipulate this trigger

I'm trying to create a trigger which will capture any event that will occur when I update any column in the table before and after updating, let's say I have 4 columns:
first_name address city country
Let's say I edited first_name lets say Jack to Henk.
It should insert in another table the command (i.e. update) ,time , description but inside the description I want it to write Jack was changed to John by current user(i.e using the current-user () function),if it is a city being updated from Mechinkova to Tostov, it should do the same do with other columns.
I know I want to have to add the concat function inside the trigger, I want it to be like this for example:
DROP TRIGGER IF EXISTS adminpanel.soft//
CREATE TRIGGER adminpanel.soft BEFORE UPDATE ON adminpanel.aggrement
FOR EACH ROW
BEGIN
INSERT INTO adminpanel.aggretrigger(cmd, time, cmd_user, last_name, city) VALUES("INSERT", NOW(), CURRENT_USER(), new.last_name, new.city);
END
//
What you are asking for is an audit trigger. It is very easy to implement.
Let us first slightly modify your main table. Let's add a field id of integer datatype as the primary key to the table, so your table would look like:
tablename
( id integer PK
, first_name varchar
, address varchar
, city varchar
, country varchar
)
Now, you will need a table, say UNIVERSAL_AUDIT_ENTRY table that will store the changes made to the data in your schema.
From what experience I have, I suggest you create this table as follows:
universal_audit_entry
( universal_audit_entryid integer PK
, table_name varchar -- captures the name of the table
, column_name varchar -- captures the name of the column
, entry_type varchar -- captures the event, e.g., 'INSERT' or 'UPDATE'
, primary_key_value integer -- captures, e.g., the value in tblename.id
, from_str varchar -- captures the value that was present before
, to_str varchar -- captures the value that was changed into
, timestamp datetime -- captures the timestamp of the event
, username varchar -- captures the name of user
)
Now with the universal_audit_entry table ready, your trigger should look somewhat like:
CREATE TRIGGER adminpanel.soft
BEFORE UPDATE ON adminpanel.aggrement
FOR EACH ROW
BEGIN
IF UPDATING(first_name) THEN
INSERT INTO universal_audit_entry VALUES
( 123 -- example for universal_audit_entryid
, 'TABLENAME'
, 'FIRST_NAME'
, 'UPDATE'
, new.id
, old.first_name
, new.first_name
, current_timestamp()
, current_user);
END IF;
END;
//
You can use similar logic to audit more columns in the same table and other tables also.
Note:
This code is not tested. I have added it here only for illustration purposes. This code for trigger is not supposed to be used directly.
new and old are the pseudo-records that are generated during an update statement. These records correspond to the rows that are being updated. :new means the row after the update statement runs and :old means the row before the update statement runs. This works in Oracle. Kindly make sure if it works in MySQL also.
EDIT
You can read more about MySQL triggers here. Read more about audit trail here and this SO question.

SQL Server 2008 - Use IDENTITY field when inserting a row

My table has 3 columns ID, ISOCode and CountryName.
Column ID is an IDENTITY column.
When I insert new records into this table, I want to populate the ISOCode field - on occasion - with the same value as the ID field.
I've tried SCOPE_IDENTITY(), ##IDENTITY and IDENT_CURRENT but none of these seems to work.
Is there a way I can do this?
you could write a trigger to update the ISOCode column
In Trigger use the code below
update T set T.ISOCode=I.ID
from your_table T
join INSERTED I
on T.ID=I.ID