I created the very simple triger and I think syntex is also correct:
CREATE TRIGGER trig1 after INSERT ON urlcontent for each row
BEGIN
insert into userpost(userid,url,hash) values (userid,url,hash);
END;
gives error:
#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 '' at line 3
Structure of both table:
CREATE TABLE urlcontent (
userid text NOT NULL,
url varchar(255) NOT NULL,
`desc` varchar(2048) NOT NULL,
preview varchar(255) NOT NULL,
img_url varchar(128) NOT NULL,
title varchar(128) NOT NULL,
`hash` varchar(128) NOT NULL,
rate varchar(20) DEFAULT NULL,
`time` varchar(64) DEFAULT NULL,
sentiment varchar(32) DEFAULT NULL,
`subject` varchar(64) DEFAULT NULL,
PRIMARY KEY (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table 'userpost'
--
CREATE TABLE userpost (
userid varchar(40) NOT NULL DEFAULT '',
url varchar(255) DEFAULT NULL,
`desc` varchar(2048) DEFAULT NULL,
preview varchar(255) DEFAULT NULL,
img_url varchar(128) DEFAULT NULL,
title varchar(128) DEFAULT NULL,
`hash` varchar(128) NOT NULL DEFAULT '',
rate varchar(16) DEFAULT NULL,
`time` varchar(64) DEFAULT NULL,
pcount varchar(16) DEFAULT NULL,
ncount varchar(16) DEFAULT NULL,
isset varchar(16) DEFAULT NULL,
sentiment varchar(32) DEFAULT NULL,
`subject` varchar(64) DEFAULT NULL,
PRIMARY KEY (userid,`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
hash and url are key in userpost table/
Structure of both table
Your specific error is likely due to the delimiter being defined as ;.
If you change the delimiter to | (in the box below the query editor) like in the following image it will work:
This helps the trigger to be created without stoping the query at the first ;.
This would work, but to insert the values from urlcontent into userpost you have to add the keywords NEW before the values. This tells the trigger that the values you want to insert in userpost are the ones that were just inserted into urlcontent:
CREATE TRIGGER trig1 AFTER INSERT ON urlcontent
FOR EACH ROW
BEGIN
insert into userpost(userid,url,hash) values (NEW.userid,NEW.url,NEW.hash);
END;
|
Related
I am trying to test out MySQL alter table to increase varchar column size.
VARCHAR(50) -> VARCHAR(100)
I try to execute command -> ALTER TABLE profile CHANGE COLUMN username username VARCHAR(100) DEFAULT NULL;
MySQL response complete with 0 row(s) affected. How is that possible?
Shouldn't increase varchar size will impact all rows within the table?
I hope to know why MySQL can process this alter table command so fast.
Below is my table script, there are total of 9209 rows.
CREATE TABLE `mytable` (
`userprofileseqid` VARCHAR(50) NOT NULL,
`clientdeviceseqid` VARCHAR(50) NOT NULL,
`userid` VARCHAR(50) NOT NULL,
`username` VARCHAR(100) DEFAULT NULL,
`usermobileno` VARCHAR(30) DEFAULT NULL,
`userstatus` VARCHAR(11) DEFAULT NULL,
`type` VARCHAR(30) DEFAULT NULL,
`role` VARCHAR(30) DEFAULT NULL,
`buscode` VARCHAR(50) DEFAULT NULL,
`distname` VARCHAR(100) DEFAULT NULL,
`distcode` VARCHAR(30) DEFAULT NULL,
`hqmobileno` VARCHAR(50) DEFAULT NULL,
`otpsubmissionblocked` INT(11) DEFAULT NULL,
`channel` VARCHAR(11) DEFAULT NULL,
`createddate` DATETIME NOT NULL,
`dealerstatus` VARCHAR(11) DEFAULT NULL,
`dealername` VARCHAR(100) DEFAULT NULL,
`email` VARCHAR(50) DEFAULT NULL,
`userfullname` VARCHAR(200) DEFAULT '',
PRIMARY KEY (`userprofileseqid`),
UNIQUE KEY `userprofile_unique_index` (`clientdeviceseqid`,`userid`,`usermobileno`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
I try on both MySQL version 5.7.20 & 8.0.28, both return 0 row(s) affected.
However, when downgrade the varchar size VARCHAR(100) -> VARCHAR(50), it will show 9209 row(s) affected without issue.
I have 2 tables, students and Math. I want to UPDATE existing data on Math.Last_name when I update the students.Last_Name using the ID I am updating in students.
Students table
CREATE TABLE `STUDENTS` (
`Date_Modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`LRN` BIGINT(12) NOT NULL AUTO_INCREMENT,
`Last_Name` VARCHAR(50) NOT NULL,
`First_Name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`LRN`)
)COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=123456789112;
MATH TABLE
CREATE TABLE `Math` (
`Date_Modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`LRN` BIGINT(12) NOT NULL,
`Last_Name` VARCHAR(50) NOT NULL,
`First_Name` VARCHAR(50) NOT NULL,
`Level` VARCHAR(3) NOT NULL,
`UT1` VARCHAR(3) NOT NULL,
`Q1` VARCHAR(50) NULL DEFAULT NULL,
`UT2` VARCHAR(50) NULL DEFAULT NULL,
`Q2` VARCHAR(50) NULL DEFAULT NULL,
`UT3` VARCHAR(50) NULL DEFAULT NULL,
`Q3` VARCHAR(50) NULL DEFAULT NULL,
`UT4` VARCHAR(50) NULL DEFAULT NULL,
`Q4` VARCHAR(50) NULL DEFAULT NULL,
`FINAL GRADE` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`LRN`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=COMPACT;
MY TRIGGER
CREATE TRIGGER `STUDENTS_after_update` AFTER UPDATE ON `STUDENTS` FOR EACH ROW BEGIN
UPDATE Math
SET Last_Name = NEW.Last_Name
WHERE LRN IN (SELECT LRN FROM Math where LRN = NEW.LRN);
END
You do not need a sub select in the update command, since for each row it will pick up the new LRN value and will update all of them in the MATH table where the new.LRN matches in the MATH table. Here how the trigger would look like
delimiter //
create trigger `STUDENTS_after_update` after update on `STUDENTS`
for each row
begin
update Math
set Last_Name = NEW.Last_Name
where LRN = NEW.LRN ;
end;//
delimiter ;
Note that I have added delimiter which is needed when you run them in the Mysql CLI, some other user interface like PHPMyadmin you need to select the delimiter from the user interface.
I have a table named Users with a column call created. Whenever a record is created I want to add the datetime.
Users Table:
CREATE TABLE `Users` (
`userId` int(11) unsigned NOT NULL AUTO_INCREMENT,
`fullName` varchar(50) DEFAULT NULL,
`firstName` varchar(25) NOT NULL DEFAULT '',
`lastName` varchar(25) NOT NULL DEFAULT '',
`address` varchar(50) NOT NULL DEFAULT '',
`city` varchar(25) DEFAULT NULL,
`state` char(2) DEFAULT NULL,
`zipCode` varchar(25) DEFAULT NULL,
`email` varchar(50) NOT NULL DEFAULT '',
`cellPhone` varchar(15) DEFAULT NULL,
`birthDate` date NOT NULL,
`creditCard` varchar(250) NOT NULL DEFAULT '',
`subscriptionStarted` date NOT NULL,
`subscriptionEnded` date NOT NULL,
`basicPlan` tinyint(1) DEFAULT NULL,
`standardPlan` tinyint(1) DEFAULT NULL,
`premiumPlan` tinyint(1) DEFAULT NULL,
`staff` tinyint(1) DEFAULT NULL,
`admin` tinyint(1) DEFAULT NULL,
`systemAdmin` tinyint(1) DEFAULT NULL,
`edited` datetime DEFAULT NULL,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=latin1;
now i added this extra query to make my created field get the current datetime when a new record is created.
ALTER TABLE Users
ALTER COLUMN created SET DEFAULT CURRENT_TIMESTAMP
The problem is that I get the following error when running the alter table query
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 'CURRENT_TIMESTAMP' at line 2
Your syntax is slightly off, I think you have to specify the column to change:
ALTER TABLE Users CHANGE created created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
See this sample SQL Fiddle for an example.
CREATE TABLE `user` (
`user_id` varchar(16) NOT NULL,
`person_id` varchar(16) NOT NULL,
`org_id` varchar(16) NOT NULL,
`email` varchar(32) NOT NULL,
`login_id` varchar(10) NOT NULL,
`password` varchar(32) NOT NULL,
`mobile_no` varchar(12) NOT NULL,
`android_id` varchar(16) NOT NULL,
`activation_status` int(2) NOT NULL,
`pin` varchar(6) NOT NULL,
`role_id` varchar(16) NOT NULL,
`imei` varchar(16) NOT NULL,
`booth_id` varchar(16) NOT NULL,
`Assignment_id` varchar(16) NOT NULL,
`created_by` varchar(16) DEFAULT NULL,
`create_date` datetime DEFAULT NULL,
`updated_by` varchar(16) DEFAULT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
(Borrowing from How to make MySQL table primary key auto increment with some prefix)
Assuming you already have your user table created, you can write a trigger to generate the id for you automatically. You'll need a dummy table to hold id's auto-generated by MySQL, allowing the trigger can easily pull new, unique ID's from.
The Dummy (Sequence) Table:
CREATE TABLE user_seq
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
The Trigger:
DELIMITER $$
CREATE TRIGGER tg_user_insert
BEFORE INSERT ON user
FOR EACH ROW
BEGIN
INSERT INTO user_seq VALUES (NULL);
SET NEW.user_id = LAST_INSERT_ID();
END$$
DELIMITER ;
I used this to handle a case where I had to generate some seed data for an existing schema (e.g. I could not change the schema). Please note I'm using this in a dev environment - no idea how performant or otherwise production-worthy something like this would be. Hopefully a competent dba can provide more insight - but since the question stands, I had a similar issue, and couldn't find an alternative, hopefully this will help someone else...
Can this trigger be changed so that the sortorder table gets 2 column values (sortOrderId, sortOrder) inserted?
How is the value of sortOrder found?
If it is known and can be inserted into image table then can it also be inserted into the sortorder table?
-- Trigger DDL Statements
DELIMITER $$
USE `nextcart`$$
CREATE
DEFINER=`root`#`localhost`
TRIGGER `nextcart`.`insert_sortorderid`
BEFORE INSERT ON `nextcart`.`image`
FOR EACH ROW
BEGIN
INSERT INTO sortorder SET sortOrderId = NULL, sortOrder = NEW.sortOrder;
SET NEW.sortOrderId = (SELECT LAST_INSERT_ID());
END;
$$
CREATE TABLE sortorder:
delimiter $$
CREATE TABLE `sortorder` (
`sortOrderId` int(11) NOT NULL AUTO_INCREMENT,
`sortOrder` tinyint(4) NOT NULL,
PRIMARY KEY (`sortOrderId`),
KEY `sort_order` (`sortOrderId`,`sortOrder`),
CONSTRAINT `fk_sortOrderId` FOREIGN KEY (`sortOrderId`) REFERENCES `image` (`imageId`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8$$
CREATE TABLE image:
delimiter $$
CREATE TABLE `image` (
`imageId` int(11) NOT NULL AUTO_INCREMENT,
`imageFileName` varchar(45) DEFAULT NULL,
`imagePath` varchar(255) DEFAULT NULL,
`imageTitle` varchar(100) DEFAULT NULL,
`imageAlt` varchar(100) DEFAULT NULL,
`imageWidth` int(11) DEFAULT NULL,
`imageHeight` int(11) DEFAULT NULL,
`classId` int(11) DEFAULT NULL,
`imageSizeId` tinyint(4) NOT NULL,
`isImageEnabled` bit(1) DEFAULT b'0',
`sortOrderId` int(11) DEFAULT NULL,
PRIMARY KEY (`imageId`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8$$
ERROR MESSAGE:
Error 1054: Unknown column 'sortOrder' in 'NEW' SQL Statement:
CREATE TRIGGER insert_sortorderid BEFORE INSERT ON image FOR EACH
ROW BEGIN INSERT INTO nextcart.sortorder SET sortOrderId = NULL,
sortOrder = NEW.sortOrder; SET NEW.sortOrderId = ( SELECT
LAST_INSERT_ID()); END; Error when running failback script. Details
follow. Error 1050: Table 'image' already exists SQL Statement: CREATE
TABLE image ( imageId int(11) NOT NULL AUTO_INCREMENT,
imageFileName varchar(45) DEFAULT NULL, imagePath varchar(255)
DEFAULT NULL, imageTitle varchar(100) DEFAULT NULL, imageAlt
varchar(100) DEFAULT NULL, imageWidth int(11) DEFAULT NULL,
imageHeight int(11) DEFAULT NULL, classId int(11) DEFAULT NULL,
imageSizeId tinyint(4) NOT NULL, isImageEnabled bit(1) DEFAULT
b'0', sortOrderId int(11) DEFAULT NULL, PRIMARY KEY (imageId)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
There is no column named sortOrder in the image table.
So, the reference to NEW.sortOrder (on the insert statement in the trigger) is invalid.
To answer your first question: No. Since there is no value supplied for that in the INSERT statement (which fires the BEFORE INSERT TRIGGER), you don't really have a source for that value.
The easy option is to provide a default value for it.
If you want to supply a value for the sortOrder column, then one option is to add a sortOrder column to the image table, and then the value can be supplied in the INSERT INTO image statement. Then it would available in the trigger.
(The purpose of the sortorder table is not at all clear.)