I am really a beginner in mysql. In oracle we can use triggers , which can detect the insert elements and allows to fully break the insert command if something is wrong. I've found that mysql also supports triggers, but how can we use them for detecting insert parameters and stopping them to be inserted if they don't satisfy rules.
e.g. INSERT INTO accounts (userId, balance) VALUES ('12','450'); // Valid
INSERT INTO accounts (userId, balance) VALUES ('12','-574'); // Invalid
if(balance<0){
Do not insert;
}
else{
Insert;
}
NOTE: I'm dealing with concurrent transactions, so STRICTLY need triggers, i.e. lowest level error detection so that no one can hack.
Any help will be appreciated. Thanks,
Or use an BEFORE INSERT trigger
DELIMITER $$
CREATE TRIGGER au_a_each BEFORE INSERT ON accounts FOR EACH ROW
BEGIN
IF new.balance > 0 THEN
BEGIN
INSERT INTO b (id,balance) VALUES (new.id, new.balance);
END
END $$
DELIMITER ;
More info in the mysql documentation : http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
PS: Programming lesson number 1(One with capital "o") - Befriend whatever programming/scripting language's documentation
You may use INSERT IGNORE and set ALTER TABLE field constraints in mysql
Related
i am inserting data from a form i want when i will insert data so the first column primary id which is using in second column as a foreign key should be increased
i have tried this code but not working
first table code
$this->db->query("insert into af_ads (ad_title,ad_pic,ad_description)
values ('$title','$filepath','$description')");
second table code
$this->db->query("insert into af_category (cat_type,ad_id_fk)
values ('$category','ad_id')");
NOTE: i want to insert ad_id into ad_id_fk
Try this:
// Your first query
$this->db->query("insert into af_ads(ad_id, ad_title, ad_pic, ad_description)
values ('', '$title', '$filepath', '$description')");
$ad_id = $this->db->insert_id(); // This returns the id that is automatically assigned to that record
// Use the id as foreign key in your second insert query
$this->db->query("insert into af_category (cat_type,ad_id_fk)
values ('$category', $ad_id)");
MySQL provides the LAST_INSERT_ID function as way to retrieve the value generated for an AUTO_INCREMENT column from the immediately preceding INSERT statement.
A lot of client libraries make this conveniently avaiable (e.g. PDO lastInsertId function.)
(I'm not familiar with CodeIgniter or ActiveRecord, so I can't speak to how that's made available.
Your code looks like it's using the PDO interface... but I'm not sure about that.
# either we need to check return from functions for errors
# or we can have PDO do the checks and throw an exception
$this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
# attempt insert which will generate AUTO_INCREMENT value
$this->db->query("INSERT (ad_id, ... ) VALUES (NULL, ...)");
# if previous insert successfully inserted a row (or rows)
$ad_id = $this->db->lastInsertId();
You really need to check whether the previous insert was successful or not. If you aren't going to code that check yourself, then PDO does provide a mechanism that performs this checking automatically, and will throw an exception if a MySQL error occurs.
I've avoided copying your original code, which looks like it's vulnerable to SQL Injection. If you're using PDO, you can make effective use of prepared statements with bind placeholders, rather than including values in the SQL text.
I am having two table consider table1 and table2. I need to do a trigger after inserting into table1.
Trigger has to do some thing like retrieving data from two other tables using select query (it retrieves more than one row) do some calculations with the data retrieved and then it need to insert it into table2 as single row.
I think it's not possible to do these with in a trigger, so I decided to call a php file from that trigger which does all those things. But some persons says calling php from a trigger is not practically good and it has some security risk.
A Simple Example will help you out.
$sql="INSERT INTO `table1` (FirstName, LastName, Age)
VALUES ('$firstname', '$lastname', '$age')";
$result = mysql_query($sql) ;
if($result)
{
// Record successfully inserted , place your code which needs to be executed after successful insertion
}
else
{
// Insertion failed
}
I assume you would be using mysqli and not mysql becuase mysql_query is deprecated as of PHP 5.5.0 but this is just an example to help you understand the logic.
Ok got you .. In this case you need to create a TRIGGER something like this.
CREATE
TRIGGER `event_name` BEFORE/AFTER INSERT/UPDATE/DELETE
ON `database`.`table`
FOR EACH ROW BEGIN
-- trigger body
-- this code is applied to every
-- inserted/updated/deleted row
END;
This Question has already been answered check the link below.
MySQL trigger On Insert/Update events
Hope this helps.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Access Auto-Increment Value During INSERT INTO Statement
I would like to generate the slug for my URLs upon creating the pages to store in the database. The slug should be title-id (e.g titlename-234). I already have the function to strip the title but how can i get the id before inserting the record?
Many thanks in advance
You should create a trigger, something like that:
CREATE TRIGGER trigger_name BEFORE INSERT ON table
FOR EACH ROW SET slug = CONCAT(NEW.title, "-", NEW.id);
I'm not sure you'll be able to access the ID column before its written on the database (unless, of course, you generate your IDs yourself, not using the autoincrement).
If you're using your DB's autoincrement (and you should be), try creating a trigger AFTER INSERT, and updating your row in your trigger. That way, even though you're updating it AFTER your insert, it'll still run before you can run any other queries (like a SELECT).
HERE is the documentation on triggers.
I was wrong. Apparently, you can't update a table you're inserting into (using an AFTER INSERT triger), it'll throw an exception. So, two possible ways to do it using SQL alone:
The ugly way:
DELIMITER $$
CREATE TRIGGER `create_slug` BEFORE INSERT
ON `events`
FOR EACH ROW
BEGIN
SET new.id = (SELECT MAX(id) FROM events) + 1;
SET new.slug = CONCAT(new.menu_name, "-", new.id);
END$$
DELIMITER ;
It overrides your database's AUTOINCREMENT. Really, don't do that.
Or, you can create a procedure:
DELIMITER $$
CREATE PROCEDURE insert_event(MenuName VARCHAR(30), Content TEXT, PhotoName TEXT)
BEGIN
INSERT INTO events (menu_name, content, photo_name) VALUES (MenuName, Content, PhotoName);
SET #id = LAST_INSERT_ID();
UPDATE events SET slug = CONCAT(menu_name, "-", #id) WHERE id = #id;
END$$
DELIMITER ;
And, instead of calling (as you were calling):
$query = mysql_query("INSERT INTO events (menu_name, content, photo_name) VALUES ('{$menu_name}', '{$content}', '{$photo_name}');", $connection);
just call
$result = mysql_query("CALL insert_event('{$menu_name}', '{$content}', '{$photo_name}');",$connection );
Again, I'll strongly advice against using mysql_query. It's outdated, discontinued and unsafe. You should check out mysqli or PDO.
I've just learned the MySQL triggers and how they work. I decided to apply it on my small website.
I have a Users table where new users accounts are created and I would like to keep a history of adding new accounts in a UsersHistory table.
The error is that when I execute the following query, it gives me an error:
Query:
CREATE TRIGGER User_After_Insert
AFTER INSERT ON UsersHistory FOR EACH ROW WHEN NOT NEW.Deleted
BEGIN
SET #changeType = 'DELETE';
INSERT INTO UsersHistory (UserID, changeType)
VALUES (NEW.ID, #changeType);
END;
CREATE TRIGGER User_After_Insert1
AFTER INSERT ON UsersHistory FOR EACH ROW WHEN NEW.Deleted
BEGIN
SET #changeType = 'NEW';
INSERT INTO UsersHistory (UserID, changeType)
VALUES (NEW.ID, #changeType);
END;
The error is:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHEN NOT NEW.Deleted
BEGIN Â
SET #changeType = 'DELE' at line 1
I looked for a solution but I couldn't find.
Thanks
Have you set a DELIMITER to something different than ";"? Also, I saw some stuff I didn't know to be supported in mysql (the WHEN statements before the BEGIN blocks), so heres my suggestion:
delimiter //
CREATE TRIGGER User_After_Insert AFTER INSERT ON UsersHistory FOR EACH ROW
INSERT INTO UsersHistory (UserID, changeType) VALUES (NEW.ID, 'NEW')//
CREATE TRIGGER User_After_Delete AFTER DELETE ON UsersHistory FOR EACH ROW
INSERT INTO UsersHistory (UserID, changeType) VALUES (OLD.ID, 'DELETE')//
delimiter ;
UPDATE
Due to your comment below, I think you need to read up on trigger a bit more mate. But here's the gist.
The above statements, create triggers in the actual database. In effect, you "install" the triggers in your database schema. Running the statements in any mysql client, will create the triggers if you have appropriate account rights.
Now, from this stage on, you dont explicitly call them from PHP or anything like that. They live in the database and are called automatically when you perform certain actions. In the above case, AFTER a record is deleted from UserHistory or AFTER a record is inserted into UserHistory.
So, when you run "INSERT INTO UserHistory VALUES ..." from your php script, the database will fire the trigger automatically.
Hope that makes sence.
Is it possible to insert a row into multiple tables at once? If you do several tables related by an ID; what is the best way to ensure integrity is maintained in case an INSERT fails?
That's exactly what transactions are for. If any of the commands fail, the whole thing since START TRANSACTION is rolled back:
START TRANSACTION;
INSERT INTO sometable VALUES(NULL,'foo','bar');
INSERT INTO someothertable VALUES (LAST_INSERT_ID(),'baz');
COMMIT;
This being MySQL, you can't use transactions with MyISAM tables (you'll need the tables to use some engine that supports this, probably InnoDB).
This will never be inserted into the table (normally you'd have some branching, e.g. an IF):
START TRANSACTION;
INSERT INTO sometable VALUES(NULL,'data','somemoredata');
ROLLBACK;
Caveat: SQL commands which change the database structure (e.g. CREATE,ALTER,DROP) cannot be rolled back!
Use transactions, luke.
MySQL can insert multiple rows (search for 'multiple rows') like this:
INSERT INTO table (field1, field2, ...) VALUES (value1, value2), (value3, value4), etc...
However, there's no way to tell what got inserted and what wasn't due to constraint violations, beyond the query returning a count of records, duplicates, and warnings. You also can't use last_insert_id() to figure out the IDs of the new rows, as that only returns the LAST id that was created, not a set of ids.
If you need to guarantee integrity, then use single row insert statements and transactions.