How do a mysql trigger after insert or update [close] - mysql

Sorry to bother you again with my questions.
I need to create a trigger in mysql to change the rows of a table.
The idea is the following:
Whenever I create a new task it will automatically create the status.
If StartDate = NULL -> status = Planning
If have endDate -> status =completed
If Have StartDate -> status =In Progress
If current date > dateBeginPrevision ->status = Overdue
Does anyone could help me please?
I dont I ask to hear the trigger, only that would give me a little help to get there, because I am a noob in mysql.
Thank you all very much.
CREATE TABLE `tasks` (
`idTask` varchar(45) NOT NULL,
`descTask` varchar(45) DEFAULT NULL,
`dateBeginPrevision` varchar(45) DEFAULT NULL,
`startDate` varchar(45) DEFAULT NULL,
`endDate` varchar(45) DEFAULT NULL,
`Priority` varchar(45) NOT NULL,
`status` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idTask`)
)
----------EDIT--------------
After this comment: "I dont think you should use trigger here, because trigger is a monitor of table, when the source table has some changes on it (insert, delete ,update)"
I chose to do this kind of checking through the java language, ie directly in my application without relying on the capabilities of the database.
Thank you.

I dont think you should use trigger here, because trigger is a monitor of table, when the source table has some changes on it (insert, delete ,update), it would invoke the trigger on it, and now ,what's your source table?

Related

SQL forcing me to use default value and property

Strange trouble indeed!
I am experiencing this issue when (My)SQL add some properties to my table, that I don´t want to be there and that I can´t change, even if I run right command and get "SUCCESS" reply.
Here is code for creating such a table:
CREATE TABLE `KIIS_EVENT_APPLICATION`
(
`ID_USER` smallint(3) unsigned NOT NULL,
`ID_EVENT` smallint(5) unsigned NOT NULL,
`COMES` timestamp,
`LEAVES` timestamp,
`TRANSPORT_THERE` varchar(30) COLLATE cp1250_czech_cs,
`TRANSPORT_BACK` varchar(30) COLLATE cp1250_czech_cs,
`ROLE` varchar(30) COLLATE cp1250_czech_cs NOT NULL,
`RELEVANCE` tinyint(1) unsigned NOT NULL,
FOREIGN KEY (`ID_EVENT`) REFERENCES `KIIS_EVENTS`(`ID_EVENT`),
FOREIGN KEY (`ID_USER`) REFERENCES `KIIS_USERS`(`ID_USER`)
) ENGINE=InnoDB DEFAULT CHARSET=cp1250 COLLATE cp1250_czech_cs
Let´s see the result:
Yellow highlighted things I don´t asked for.
If I run query, such as
ALTER TABLE `KIIS_EVENT_APPLICATION` CHANGE `COMES` `COMES` TIMESTAMP NOT NULL;
page says, it is successfully done, but nothing changes.
How can i make COMES column to be same as LEAVES column ?
Could it be caused by missing primary key? Do I need one when I have 2 foreign there (is it good SQL design practice, or?) ?
Michael - sqlbot got it right in comment.
ALTER TABLE KIIS_EVENT_APPLICATION MODIFY COLUMN COMES TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00'; or more correctly, ... TIMESTAMP NULL DEFAULT NULL
The first timestamp column in a table gets magical behavior by default prior to MySQL Server 5.6.
I added
timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
properties to all columns with such a behaviour and it works just fine.
Great!

Setting up MySQL trigger syntax correctly and carefully

I've been doing a lot of new learning about MySQL and triggers. I think I understand the concept and I realise there are a LOT of possible dangers in using them. However I believe the limited use of them is correct for the function I want to perform.
I have 9 tables which correspond to 9 different web based Ajax engined forms. I've worked hard on these, being my first time using Ajax, and I'm reasonably happy with them. Each time a user makes a change to whichever form they are filling out, the change is Ajaxed back to the DB and they get a confirmation or error response. Fairly straight forward. Each forms respective table has a "status" field, a "lastModified" field and a field I call "agRef" which is sort of like status but is null until the form reaches a certain stage, further along the process.
I have an additional table called "records" which is where all entries in any of the other tables, is listed so we can easily see what forms have been started, when their last changes were made and what status's they have. So here is where I believe the trigger part should work, so that I don't have to make updates to the "records" table in my php on every single transaction.
The "records" table is set out like this:
`uaID` int(11) NOT NULL AUTO_INCREMENT,
`uID` int(11) NOT NULL,
`appNo` int(11) NOT NULL,
`applicationKey` varchar(8) NOT NULL,
`appID` int(11) DEFAULT NULL,
`applicationName` varchar(64) NOT NULL,
`agRef` varchar(32) DEFAULT NULL,
`status` varchar(32) NOT NULL,
`dateStarted` int(11) NOT NULL,
`lastModified` int(11) NOT NULL,
Now all of these fields are populated at the same time the matching entry is inserted into which ever one of the other 9 tables the form connects to. A small example of one of the other 9 tables would look like this:
`appID` int(11) NOT NULL AUTO_INCREMENT,
`uID` int(11) NOT NULL,
`uaID` int(11) NOT NULL,
`status` varchar(32) NOT NULL DEFAULT 'Data Acquisition',
`agRef` varchar(32) DEFAULT NULL,
`groupName` varchar(64) DEFAULT NULL,
`shortTitle` varchar(64) DEFAULT NULL,
`recipient` varchar(64) DEFAULT NULL,
`partOfValCh` varchar(64) DEFAULT NULL,
`sector` varchar(64) DEFAULT NULL,
`subSector` varchar(64) DEFAULT NULL,
`topic` varchar(64) DEFAULT NULL,
<snip because this can go on for a lot of lines>
`dateStarted` int(11) NOT NULL,
`lastModified` int(11) NOT NULL,
agRef on both tables remain null for now, appID is null on the records table initially at the point of creation but is updated immediately as soon as the corresponding entry is made into the second table, where it is generated by auto increment and then a call is made back to my records table to insert the appID there.
The three things that will change from any of the data tables are the three fields "status", "agRef", "lastModified".
So I'm trying to create a trigger that will do this after each alteration/update to the data table, so that the data in my records table is consistent and accurate.
This is my first ever trigger set up attempt:
DELIMITER $$
CREATE TRIGGER `dataTableOne_to_records_sync` AFTER UPDATE ON `dataTableOne`
FOR EACH ROW BEGIN
UPDATE records (agRef, status, lastModified) VALUES (NEW.agRef, NEW.status, NEW.lastModified) WHERE appID = OLD.appID;
END$$
DELIMITER ;
I am trying to set this up through phpmyadmin, but it is returning an error telling me I have a syntax problem within my UPDATE line. I feel that it is an issue with the WHERE part - the appID is the one common element that ties the row in "records" to the row being updated/changed in "dataTableOne". How do I set this up correctly? Is my error something more serious, and am I running the risk of creating a huge mess, like a never ending loop? I'm a bit paranoid about doing this for the first time. Thanks in advance for help and advice.
UPDATE I have now tried a few other trigger attempts but although MySQL will accept them as being valid trigger syntax, they always seem to break the entire DB functionality. Can anyone help me with my trigger syntax to get it to work correctly? In the demo tables above, if the SECOND table gets updated at all, I want the three fields copied over into the FIRST table by the trigger. The three values I want copied across are "status", "agRef", and "lastModified".
My most recent failed attempt was this:
CREATE TRIGGER AIGltInq_sync AFTER INSERT ON app_AIGltInq
FOR EACH ROW
UPDATE records r
SET r.agRef = NEW.agRef
, r.status = NEW.status
, r.lastModified = NEW.lastModified
WHERE uaID = NEW.uaID;
I'm not at all familiar with that form of the UPDATE statement.
To change values of columns in rows, we'd typically write an UPDATE statement like this:
UPDATE records r
SET r.agRef = NEW.agRef
, r.status = NEW.status
, r.lastModified = NEW.lastModified
WHERE r.appId = OLD.appID
Reference: https://dev.mysql.com/doc/refman/5.5/en/update.html
Question withdrawn. Triggers are seriously best to avoid, as they tend to cause more breakages than they fix! Most recommendations tend towards handling the function with whatever scripting language you are using to talk with the DB. In my case this is PHP and PHP is now performing all of the functionality I was hoping to short-cut by using triggers. Lesson? Don't take short-cuts when wanting to do the job right. :)

WordPress WP-Dbmanager 0/1 Query(s) Executed Successfully

WordPress 3.5.1
WP-DBManager 2.63
Database Type MYSQL
Database Version v5.1.68-cll
Trying to create new table on database for WordPress site using the WP-DBManager plugin.
I click on the Run SQL Query link in the Admin panel and paste in my query which is
CREATE TABLE mg_msl_lookup
(
device_id INT(11) NOT NULL auto_increment,
sku VARCHAR(30) NOT NULL,
manufacturer VARCHAR(30) NOT NULL,
phone VARCHAR(50) NOT NULL,
esn BIGINT(18) NOT NULL,
msl INT(6) NOT NULL
);
I click Run and I get the error message
CREATE TABLE mg_msl_lookup
0/1 Query(s) Executed Successfully
So I did a google search for "WP-Dbmanager 0/1 Query(s) Executed Successfully" and found this forum post on the plugin developer's site. It suggested to put the statement all on one line, so I did:
CREATE TABLE mg_msl_lookup (Device_Id int(11) NOT NULL AUTO_INCREMENT, SKU varchar(30) NOT NULL, Manufacturer varchar(30) NOT NULL, Phone varchar(50) NOT NULL, ESN bigint(18) NOT NULL, MSL int(6) NOT NULL);
Once again I click Run and I get the error message:
CREATE TABLE mg_msl_lookup (Device_Id int(11) NOT NULL AUTO_INCREMENT, SKU varchar(30) NOT NULL, Manufacturer varchar(30) NOT NULL, Phone varchar(50) NOT NULL, ESN bigint(18) NOT NULL, MSL int(6) NOT NULL);
0/1 Query(s) Executed Successfully
I have site wide admin permissions, I can drop/empty tables using the plugin GUI, but for some reason can't create a simple table. I have 40 tables before and after I run the statement.
The plugin developer has these set of instructions on the Run Query page
CREATE statement will return an error, which is perfectly normal due to the database class. To confirm that your table has been created check the Manage Database page.
UPDATE statement may return an error sometimes due to the newly updated value being the same as the previous value.
ALTER statement will return an error because there is no value returned.
I'm gathering that what he means in #1 is that when you run a CREATE statement it will error (so perhaps 0/1 Query(s) Executed Successfully is normal?) so I followed the directions and go back to the Manage Database page but my new table is not there.
Does anyone have any experience with the WP-DBManager that could assist with this ? This is getting rather frustrating.
I opted to use phpMyAdmin to create the tables instead of the plugin, worked like a charm.

Database schema advice

I'm creating a membership directory for an organization and I'm trying to figure out a nice way to keep everyone's details in order and updateable manner. I have 3 tables:
Person table handles the actual person
CREATE TABLE `person` (
`personid` BIGINT PRIMARY KEY AUTO_INCREMENT,
`personuuid` CHAR(32) NOT NULL,
`first_name` VARCHAR(50) DEFAULT '',
`middle_name` VARCHAR(50) DEFAULT '',
`last_name` VARCHAR(50) DEFAULT '',
`prefix` VARCHAR(32) DEFAULT '',
`suffix` VARCHAR(32) DEFAULT '',
`nickname` VARCHAR(50) DEFAULT '',
`username` VARCHAR(32) ,
`created_on` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` CHAR(33) DEFAULT '000000000000000000000000000000000',
`last_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`last_updated_by` CHAR(33) DEFAULT '000000000000000000000000000000000'
) ENGINE=InnoDB, COMMENT='people';
Information about a person. Such as school, phone number, email, twitter name, etc. All of these values would be stored in 'value' as a json and my program will handle everything. On each update by the user a new entry is created to show the transition of changes.
CREATE TABLE `person_info` (
`person_infoid` BIGINT PRIMARY KEY AUTO_INCREMENT,
`person_infouuid` CHAR(32) NOT NULL,
`person_info_type` INT(4) NOT NULL DEFAULT 9999,
`value` TEXT,
`created_on` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` CHAR(33) DEFAULT '000000000000000000000000000000000',
`last_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`last_updated_by` CHAR(33) DEFAULT '000000000000000000000000000000000'
) ENGINE=InnoDB, COMMENT="Personal Details";
A map between person and person_info tables
CREATE TABLE `person_info_map` (
`personuuid` CHAR(32),
`person_infouuid` CHAR(32) ,
`created_on` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_by` CHAR(33) DEFAULT '000000000000000000000000000000000',
`is_active` INTEGER(1)
) ENGINE=InnoDB, COMMENT="Map between person and person info";
So given that I am creating a new entry into person_info everytime there is an update, I'm wondering if I should worry about i/o errors, tables getting to big, etc. And if so, what are possible solutions? I've never really worked with database schemas like this so I figure I should ask for help rather than get screwed in the future.
I'm sure some might ask how often the updates might occur. Truthfully I'm not expecting too much. We currently have 2k members in our directory and I don't expect us to ever have more than 10k active members at any time. I'm also thinking that we will have at most 50 different option types, but for safety and future purposes I allow up to 1000 different option types.
Considering this small piece, does anyone have any advice as to how I should proceed from here?
The person to person_info relationship seems like it should be modeled as a one-to-many relationship (i.e one person records has many person_info records). If that is true, the person_info_map can be dropped as it serves no purpose.
Do not use the UUID fields to establish relationships between your tables. Use the primary keys and create foreign key constraints on them. This will enforce data integrity and improve the performance of joins when querying.
I would personally have the 2 tables merged as the view of the person at the current moment, and have another table where you write the changes (like an event store).
That will avoid you to join the 2 tables every single time you need to fetch the person.
But that's now from the application point of view. I hear already the DBA shouting in my ears :)
So no one really answered the question so I'll post what I ended up doing. I don't know if it will work yet as our systems aren't active, but I think it should work.
I went ahead and kept the system we have above. I'm hoping that we won't ever hit too many rows that it will become an issue, but if we do then I plan on archiving a chunk of the 'old' data. I think that will help, but I think machines will likely our pace of usage.

Codeigniter query create federated table

I'm trying to create a table with this function in Codeigniter
public function createTable($connectionString) {
$createString = "CREATE TABLE {$this->getTabela()} (
`data` datetime NOT NULL,
`idempregado` varchar(45) DEFAULT NULL,
`nif` varchar(15) DEFAULT NULL,
`idsociedade` bigint(20) DEFAULT NULL,
`tipo` varchar(45) DEFAULT NULL,
PRIMARY KEY (`data`),
KEY `fk_assiduidade_user1` (`idempregado`,`nif`,`idsociedade`),
CONSTRAINT `fk_assiduidade_user1` FOREIGN KEY (`idempregado`, `nif`, `idsociedade`) REFERENCES `user` (`idempregado`, `nif`, `idsociedade`) ON DELETE NO ACTION ON UPDATE NO ACTION
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8
CONNECTION='$connectionString'";
var_dump($createString);
var_dump($this->getDbConnect()->conn_id);
var_dump($this->getDbConnect()->query($createString));
}
But the query is always returning False.
As you guys can see i already made 3 var_dumps to check if its all OK.
Ca you guys help me get to the point where this don't execute the query?
Regards,Elkas
I just found the problem.
After talking with technicians at the Data center (because i dont have access to any logs) i found that they have the FEDERATED engine disabled.
Problem Solved.
Thanks for the tips.