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
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, "]", ".")
)
;
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 |
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.
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
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