MSSQL Try Catch and Set Identity Insert in MySQL? - mysql

Do you know how to rewrite these this query in MySQL ?
I can't find Identity insert, I can't find any try catch,
I don't understand it.
CREATE TRIGGER T1 ON DB1.dbo.A
AFTER INSERT AS
BEGIN TRY
SET IDENTITY_INSERT DB2.dbo.B ON
INSERT INTO dbo.B(id, text) SELECT A.id,A.text FROM dbo.A INNER JOIN inserted I ON I.id = A.id
SET IDENTITY_INSERT DB2.dbo.B OFF
SET IDENTITY_INSERT DB2.dbo.D ON
INSERT INTO dbo.D(id, text) SELECT A.id,A.text FROM dbo.A INNER JOIN inserted I ON I.id = A.id
SET IDENTITY_INSERT DB2.dbo.D OFF
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
SET IDENTITY_INSERT DB2.dbo.B OFF
SET IDENTITY_INSERT DB2.dbo.D OFF
END CATCH
GO

MySQL triggers have implicit transaction support, so the trigger cannot use statements that explicitly or implicitly begin or end a transaction such as START TRANSACTION, COMMIT, or ROLLBACK.
It is not necessary in MySQL to enable the insertion of values into primary key columns - this is already allowed. You can, however, toggle foreign key constraint checking and unique index checking:
http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_unique_checks
A common way to do this is to store the existing values in user variables, change the settings, then restore the settings after your script is complete:
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
-- Your SQL statements here.
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
I'm not sure why you would need to do that in your trigger, so your MySQL trigger would look something like this:
DELIMITER |
CREATE TRIGGER T1 AFTER INSERT ON A FOR EACH ROW
BEGIN
INSERT INTO B (id, text) VALUES (NEW.id, NEW.text);
INSERT INTO C (id, text) VALUES (NEW.id, NEW.text);
END;|
DELIMITER ;
Here's the results of a quick test:
CREATE TABLE `A` (
`id` int(11) NOT NULL auto_increment,
`text` varchar(255) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `B` (
`id` int(11) NOT NULL auto_increment,
`text` varchar(255) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `C` (
`id` int(11) NOT NULL auto_increment,
`text` varchar(255) default NULL,
PRIMARY KEY (`id`)
);
DELIMITER |
CREATE TRIGGER T1 AFTER INSERT ON A FOR EACH ROW
BEGIN
INSERT INTO B (id, text) VALUES (NEW.id, NEW.text);
INSERT INTO C (id, text) VALUES (NEW.id, NEW.text);
END;|
DELIMITER ;
INSERT INTO `A` (id, text) VALUES (1, 'Line 1');
INSERT INTO `A` (id, text) VALUES (2, 'Line 3');
INSERT INTO `A` (id, text) VALUES (3, 'Line 3');
SELECT * FROM `A`;
+----+--------+
| id | text |
+----+--------+
| 1 | Line 1 |
| 2 | Line 3 |
| 3 | Line 3 |
+----+--------+
SELECT * FROM `B`;
+----+--------+
| id | text |
+----+--------+
| 1 | Line 1 |
| 2 | Line 3 |
| 3 | Line 3 |
+----+--------+
SELECT * FROM `C`;
+----+--------+
| id | text |
+----+--------+
| 1 | Line 1 |
| 2 | Line 3 |
| 3 | Line 3 |
+----+--------+
If you want something similar to TRY ... CATCH, you'll need to use handlers instead:
http://dev.mysql.com/doc/refman/5.1/en/declare-handler.html
Here's the documentation on MySQL triggers:
http://dev.mysql.com/doc/refman/5.1/en/commit.html

Just set id column to AUTO_INCREMENT. You don't need to toggle something on and off.
Read more in documentation

Related

Trigger value, call for table column and concenate with text

I am not able to solve that [CREATE TRIGGER VALUE] needs to call for table content and concatenate with text. For details of expected result, see below result area.
Currently the code can be run In one execution, creating 2 lines in account_log as expected.
I have marked the line that I suspect needs to be update with [<-- Needs update?].
CREATE DATABASE IF NOT EXISTS test6;
USE test6;
DROP TABLE IF EXISTS account;
CREATE TABLE account
(
`id` CHAR(4) PRIMARY KEY,
`name` VARCHAR(25),
`price` DECIMAL(4, 2)
);
DROP TABLE IF EXISTS account_log;
CREATE TABLE account_log
(
`log_id` INTEGER PRIMARY KEY AUTO_INCREMENT,
`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`description` VARCHAR(60)
);
DELETE FROM account;
INSERT INTO account
VALUES
('1', 'Adam', 10),
('2', 'Eva', 7)
;
DROP PROCEDURE IF EXISTS product_update;
DELIMITER ;;
CREATE PROCEDURE product_update()
BEGIN
UPDATE account
SET
name = "Ad"
WHERE
id = "1";
END
;;
DELIMITER ;
DROP TRIGGER IF EXISTS after_account_update;
CREATE TRIGGER after_account_update
AFTER UPDATE
ON account
FOR EACH ROW
INSERT INTO
account_log (`description`)
VALUES
('Update detected: Productid: [product-1]') -- <-- Needs update?
;
-- ----------------------------
-- Provoke triggers to execute.
-- ----------------------------
CALL product_update();
CALL product_update();
SELECT * FROM account_log;
Results:
The result looks currently like this:
(the content of description is plain text).
+--------+---------------------+-----------------------------------------+
| log_id | timestamp | description |
+--------+---------------------+-----------------------------------------+
| 1 | 2019-03-28 18:14:58 | Update detected: Productid: [product-1] |
| 2 | 2019-03-28 18:14:58 | Update detected: Productid: [product-1] |
+--------+---------------------+-----------------------------------------+
I need the result to look like this
(where the values 1 and 2 in table description, comes from table account, column [id]):
+--------+---------------------+-----------------------------------------+
| log_id | timestamp | description |
+--------+---------------------+-----------------------------------------+
| 1 | 2019-03-28 18:14:58 | Update detected: Productid: 1 |
| 2 | 2019-03-28 18:14:58 | Update detected: Productid: 2 |
+--------+---------------------+-----------------------------------------+
It works by using below TRIGGER VALUES CONCAT:
CREATE TRIGGER after_account_insert
AFTER INSERT
ON account
FOR EACH ROW
INSERT INTO
account_log (`description`)
VALUES
(
CONCAT("Update detected: Productid: ", "[", NEW.id, "]", ".")
)
;

What is the best way to generate primary key automatically?

I want to generate my primary key automatically in MySQL data table. But I want it to be a character string though in sequence.
Example:
user_id (Primary Key)
USER000001
USER000002
USER000003
USER000004 ....and so on..
By separate table for sequencing and a trigger, you can generate PK automatically with your format.
Tables
CREATE TABLE tableName_seq
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE tableName
(
id VARCHAR(10) NOT NULL PRIMARY KEY DEFAULT '0', name VARCHAR(30)
);
Now the trigger
DELIMITER $$
CREATE TRIGGER tg_table_insert
BEFORE INSERT ON tableName
FOR EACH ROW
BEGIN
INSERT INTO tableName_seq VALUES (NULL);
SET NEW.id = CONCAT('USER', LPAD(LAST_INSERT_ID(), 6, '0'));
END$$
DELIMITER ;
Then you just insert rows to table
INSERT INTO tableName (name)
VALUES ('Jhon'), ('Mark');
And you'll have
| ID | NAME |
------------------
| USER000001 | Jhon |
| USER000002 | Mark |

How to make SQL Server 2008 table primary key auto increment with some prefix

The given query is in mysql format. I want same query in SQL Server 2008.
CREATE TABLE table1_seq
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE table1
(
id VARCHAR(7) NOT NULL PRIMARY KEY DEFAULT '0', name VARCHAR(30)
);
Now the trigger
DELIMITER $$
CREATE TRIGGER tg_table1_insert
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO table1_seq VALUES (NULL);
SET NEW.id = CONCAT('LHPL', LPAD(LAST_INSERT_ID(), 3, '0'));
END$$
DELIMITER ;
Then you just insert rows to table1
INSERT INTO Table1 (name)
VALUES ('Jhon'), ('Mark');
And you'll have
| ID | NAME |
------------------
| LHPL001 | Jhon |
| LHPL002 | Mark |
This may answer your question
-- create table with 'ABCD' as prefix, combining with identity column Id
CREATE TABLE dbo.Persons
(
Id int IDENTITY (1,1) NOT NULL
,PersonId AS ('ABCD' + CONVERT(varchar(20), Id)) PERSISTED NOT NULL PRIMARY KEY
,Name varchar(100)
);
GO
-- Do not specify calculated column when insert values into the table
INSERT INTO dbo.Persons (Name)
VALUES ('Person1'), ('Person2'), ('Person3');
GO
-- Display the records from the table
SELECT PersonId, Name
FROM dbo.Persons;
GO
This approach does not require to create a separate table and trigger, therefore efficient.
Hope this helps.

Two primary keys & auto increment

I have a MySQL table with two fields as primary key (ID & Account), ID has AUTO_INCREMENT.
This results in the following MySQL table:
ID | Account
------------------
1 | 1
2 | 1
3 | 2
4 | 3
However, I expected the following result (restart AUTO_INCREMENT for each Account):
ID | Account
------------------
1 | 1
2 | 1
1 | 2
1 | 3
What is wrong in my configuration? How can I fix this?
Thanks!
Functionality you're describing is possible only with MyISAM engine. You need to specify the CREATE TABLE statement like this:
CREATE TABLE your_table (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
account_id INT UNSIGNED NOT NULL,
PRIMARY KEY(account_id, id)
) ENGINE = MyISAM;
If you use an innoDB engine, you can use a trigger like this:
CREATE TRIGGER `your_table_before_ins_trig` BEFORE INSERT ON `your_table`
FOR EACH ROW
begin
declare next_id int unsigned default 1;
-- get the next ID for your Account Number
select max(ID) + 1 into next_id from your_table where Account = new.Account;
-- if there is no Account number yet, set the ID to 1 by default
IF next_id IS NULL THEN SET next_id = 1; END IF;
set new.ID= next_id;
end#
Note ! your delimiter column is # in the sql statement above !
This solution works for a table like yours if you create it without any auto_increment functionality like this:
CREATE TABLE IF NOT EXISTS `your_table` (
`ID` int(11) NOT NULL,
`Account` int(11) NOT NULL,
PRIMARY KEY (`ID`,`Account`)
);
Now you can insert your values like this:
INSERT INTO your_table (`Account`) VALUES (1);
INSERT INTO your_table (`Account`, `ID`) VALUES (1, 5);
INSERT INTO your_table (`Account`) VALUES (2);
INSERT INTO your_table (`Account`, `ID`) VALUES (3, 10205);
It will result in this:
ID | Account
------------------
1 | 1
2 | 1
1 | 2
1 | 3

mysql inserting data into multiple tables

My tables are students, class, and studentclasses. They have many to many relationships among them. Can anyone tell me why the following code is not working?
START TRANSACTION;# MySQL returned an empty result set (i.e. zero rows).
# MySQL returned an empty result set (i.e. zero rows).
INSERT INTO 'students'('StudentID','Fname','Lname')
VALUES (Null,'name','lastname')
# 1 row affected.
SET #student = LAST_INSERT_ID();
# MySQL returned an empty result set (i.e. zero rows).
INSERT INTO `classes`(`classID`, `className`)
VALUES (Null, 'Maths');# 1 row affected.
SET #class = LAST_INSERT_ID();
# MySQL returned an empty result set (i.e. zero rows).
INSERT INTO `studentclasses`(`classID`, `studentID`)
VALUES (#class, #student);
# 1 row affected.
COMMIT;# MySQL returned an empty result set (i.e. zero rows).
START TRANSACTION;
INSERT INTO students(StudentID,Fname,Lname) VALUES (Null,'name','lastname');
SET #student = LAST_INSERT_ID();
INSERT INTO classes(classID, className) VALUES (Null, 'Maths');
SET #class = LAST_INSERT_ID();
INSERT INTO studentclasses(classID, studentID) VALUES(#class, #student);
COMMIT;
It should work, try this example on new database -
CREATE TABLE classes(
classID INT(11) NOT NULL AUTO_INCREMENT,
className VARCHAR(20) DEFAULT NULL,
PRIMARY KEY (classID)
);
CREATE TABLE studentclasses(
classID INT(11) DEFAULT NULL,
studentID INT(11) DEFAULT NULL
);
CREATE TABLE students(
StudentID INT(11) NOT NULL AUTO_INCREMENT,
Fname VARCHAR(20) DEFAULT NULL,
Lname VARCHAR(20) DEFAULT NULL,
PRIMARY KEY (StudentID)
);
START TRANSACTION;
INSERT INTO students(StudentID,Fname,Lname) VALUES (Null,'name','lastname');
SET #student = LAST_INSERT_ID();
INSERT INTO classes(classID, className) VALUES (Null, 'Maths');
SET #class = LAST_INSERT_ID();
INSERT INTO studentclasses(classID, studentID) VALUES(#class, #student);
COMMIT;
SELECT * FROM students;
+-----------+-------+----------+
| StudentID | Fname | Lname |
+-----------+-------+----------+
| 1 | name | lastname |
+-----------+-------+----------+
SELECT * FROM classes;
+---------+-----------+
| classID | className |
+---------+-----------+
| 1 | Maths |
+---------+-----------+
SELECT * FROM studentclasses;
+---------+-----------+
| classID | studentID |
+---------+-----------+
| 1 | 1 |
+---------+-----------+
use Insert statements in try block and catch the exception. if exception occur then do rollback