I have 3 tables:
create table users (
id int auto_increment primary key,
first_name varchar(40) not null,
last_name varchar(40) not null,
email varchar(40) not null,
password varchar(40) not null,
deleted tinyint(1) not null default 0
) engine = InnoDB;
create table comments (
id int auto_increment primary key,
task_id int not null,
foreign key fk_comment_task(task_id) references tasks(id),
user int not null,
foreign key fk_comment_user(user) references users(id),
comment varchar(1000) not null,
comment_date date not null,
viewed tinyint(1) not null default 0,
deleted tinyint(1) not null default 0
) engine = InnoDB;
create table viewed_comments (
id int auto_increment primary key,
comment int not null,
foreign key fk_viewed_comment(comment) references comments(id),
viewer int not null,
foreign key fk_viewed_viewer(viewer) references users(id),
unread tinyint(1) not null default 0,
deleted tinyint(1) not null default 0
) engine = InnoDB;
I made a trigger that creates rows in viewed_comments for every user in the users table that is not the user that submitted the comment:
delimiter |
create trigger ins_views after insert on comments
for each row
begin
DECLARE finished INT DEFAULT 0;
DECLARE id INT DEFAULT 0;
DECLARE currentId CURSOR FOR SELECT id FROM users WHERE id != NEW.user;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN currentId;
update_views_loop: LOOP
FETCH currentId INTO id;
IF finished = 1 THEN LEAVE update_views_loop; END IF;
INSERT INTO viewed_comments (comment, viewer) VALUES (NEW.id, id);
END LOOP update_views_loop;
CLOSE currentId;
END;
|
delimiter ;
The problem is that when I try to insert a comment such as
insert into comments (task_id, user, comment, comment_date) values (24, 6, 'test', '2018-3-5');
It fails saying the 'Cannot add or update a child row: a foreign key constraint fails (viewed_comments, CONSTRAINT fk_viewed_viewer FOREIGN KEY (viewer) REFERENCES users (id)). When I change the trigger on the insert line to the following it works to a degree:
INSERT INTO viewed_comments (comment, viewer) VALUES (NEW.id, 6);
On this sample set I have 3 users, and on the viewed_comments table I get 3 new rows, instead of 2. I'm not sure how to troubleshoot this in MySQL or how to print the variables to see the values as it happens. It seems on the cursor line New keyword is disregarded resulting in 3 rows instead of 2. But, then it has a value on the insert statement, but the cursor doesn't have any values. I am using MariaDB 10.4.11 How do I fix this?
Related
I have defined the following trigger on my database in phpMyAdmin:
It's a very simple trigger where I just insert a record into the history table after an insert in the item table:
insert into history values(null, new.Id, new.LocationId, new.LocationId, new.PersonId, new.PersonId, date(now()))
However, the trigger is not firing (and it worked correctly when I tested it in MySQL Workbench).
Edit 1:
The trigger fires when I define it with some dummy values, like this:
insert into history values(null, 1, 1, 1, 1, 1, date(now()))
Edit 2:
The history table is written into when I define the trigger with dummy values (see edit 1). But the most recently added entry's ID is 11 (ID is auto_increment), even though the last entry before that had ID = 3. My point is that they are not consecutive, but rather as if there were entries in between but were deleted for some reason...
Edit 3:
Here is the DDL for item and history tables:
create table Item
(
Id int not null auto_increment primary key,
InventoryNumber int not null unique,
ItemStatus varchar(20) not null,
ItemType varchar(30) not null,
ItemName varchar(100) not null,
PurchaseDate date not null,
PurchaseValue decimal(12,4) not null,
Amortization decimal(12,4) not null,
LocationId int not null,
PersonId int not null,
foreign key(PersonId) references Person(Id),
foreign key(LocationId) references Location(Id)
);
create table History
(
Id int not null auto_increment primary key,
ItemId int not null,
OldLocationId int not null,
NewLocationId int not null,
OldPersonId int not null,
NewPersonId int not null,
DateOfChange date not null,
foreign key(ItemId) references Item(Id),
foreign key(OldLocationId) references Location(Id),
foreign key(NewLocationId) references Location(Id),
foreign key(OldPersonId) references Person(Id),
foreign key(NewPersonId) references Person(Id)
);
and the trigger (which I think is irrelevant since I didn't import the trigger via a script, I defined it using phpMyAdmin's GUI):
DELIMITER //
CREATE TRIGGER historyTriggerInsert AFTER INSERT ON Item
FOR EACH ROW
BEGIN
insert into History values(null, new.Id, new.LocationId, new.LocationId, new.PersonId, new.PersonId, date(now()));
END;//
DELIMITER ;
And here is another thing I found out: when I add an entry to item using my Yii web application, the entry is visible in the item table in phpMA, but the trigger inserts nothing into the history table. However, when I add an entry to item directly in phpMA, the trigger also creates an entry in history i.e. it works correctly.
Also, when I define the trigger with those dummy values but only leave new.Id, like this:
insert into history values(null, new.Id, 1, 1, 1, 1, date(now()))
it also doesn't work. This and the incrementing ID leads me to a conclusion that the trigger is fired, tries to insert into history, but for some reason gets an invalid new.Id value.
I am developing a Yii2 framework application and during my data modelling phase I decided to let DB engine handle simple updates and maintain my counter tables (which are used to return the number of unread messages and other stuff for the user).
I have designed a trigger on message table to increase and decrease number of unread messages for the user.
User can be either client or architect.
All of my id columns in the DB are UNSIGNED INTs (these are also the PK for respective tables).
I have a problem when forward engineering from Workbench. I have made a script with test data for integrity testing and initial population. The script executed fine, before I added the AFTER_INSERT trigger for the message table.
Here is the trigger code:
CREATE DEFINER = CURRENT_USER TRIGGER `visavis`.`message_AFTER_INSERT` AFTER INSERT ON `message` FOR EACH ROW
BEGIN
DECLARE archid INT UNSIGNED;
# Cheks if recevier is an architect
SELECT IFNULL(`visavis`.`architect`.`id`,0)
INTO archid
FROM `visavis`.`architect`
WHERE `visavis`.`architect`.`user` = NEW.`to`;
# Checks if the new message is set to sent (and not read)
IF NEW.status = 1
THEN
IF archid = 0 -- if the receiver is client
THEN
# Checks if the user receiving exists in the user_counter table
IF NOT EXISTS (SELECT 1 FROM `visavis`.`user_counter` WHERE `visavis`.`user_counter`.`user` = NEW.`to`)
THEN
# Insert new row into user_counter table
INSERT INTO `visavis`.`user_counter` (`user`,`messages`) VALUES (NEW.`to`,1);
ELSE
# Add one to the user followings counter
UPDATE `visavis`.`user_counter`
SET `visavis`.`user_counter`.`messages` = `visavis`.`user_counter`.`messages` + 1
WHERE `visavis`.`user_counter`.`user` = NEW.`to`;
END IF; -- if user_counter
ELSE
# Extra check if archid is null
#IF ISNULL(archid)
#THEN
# SET archid = 1; -- Testing value
#END IF;
# Checks if the architect receiving exists in the architect_counter table
IF NOT EXISTS (SELECT 1 FROM `visavis`.`architect_counter` WHERE `visavis`.`architect_counter`.`architect` = archid)
THEN
# Insert new row into architect_counter table
INSERT INTO `visavis`.`architect_counter` (`architect`,`messages`) VALUES (archid,1);
ELSE
# Add one to the user followings counter
UPDATE `visavis`.`architect_counter`
SET `visavis`.`architect_counter`.`messages` = `visavis`.`architect_counter`.`messages` + 1
WHERE `visavis`.`architect_counter`.`architect` = archid;
END IF; -- if architect_counter
END IF; -- if receiver is client
END IF; -- if message is sent
END
The problem is that I get this error:
ERROR: Error 1048: Column 'architect' cannot be null
In the code above in the ELSE branch of the client or architect check I inserted the extra check code to assign value to the variable (it is commented out). With this code script passes fine, but all unread messages end up with architect with id=1.
I am also adding my tables' DDLs:
CREATE TABLE IF NOT EXISTS `architect` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'A PK for the table.',
`user` INT UNSIGNED NOT NULL COMMENT 'Link to the user that is the architect.',
`office` INT UNSIGNED NULL COMMENT 'Link to the architect\'s office, if any.',
`short_description` INT UNSIGNED NOT NULL COMMENT 'Link to the text of short description.',
`description` INT UNSIGNED NOT NULL COMMENT 'Link to the text of description.',
`specialty_1` INT UNSIGNED NULL COMMENT 'Link to the specialty.',
`specialty_2` INT UNSIGNED NULL COMMENT 'Link to the specialty.',
`specialty_3` INT UNSIGNED NULL COMMENT 'Link to the specialty.',
`order` INT UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_architect_specialty_1`
FOREIGN KEY (`specialty_1`)
REFERENCES `specialty` (`id`)
ON DELETE SET NULL
ON UPDATE NO ACTION,
CONSTRAINT `fk_architect_specialty_2`
FOREIGN KEY (`specialty_2`)
REFERENCES `specialty` (`id`)
ON DELETE SET NULL
ON UPDATE NO ACTION,
CONSTRAINT `fk_architect_specialty_3`
FOREIGN KEY (`specialty_3`)
REFERENCES `specialty` (`id`)
ON DELETE SET NULL
ON UPDATE NO ACTION,
CONSTRAINT `fk_architect_short_description`
FOREIGN KEY (`short_description`)
REFERENCES `text` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION,
CONSTRAINT `fk_architect_description`
FOREIGN KEY (`description`)
REFERENCES `text` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION,
CONSTRAINT `fk_architect_office`
FOREIGN KEY (`office`)
REFERENCES `office` (`id`)
ON DELETE SET NULL
ON UPDATE NO ACTION,
CONSTRAINT `fk_architect_user`
FOREIGN KEY (`user`)
REFERENCES `user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
COMMENT = 'The info about the architect.';
CREATE TABLE IF NOT EXISTS `visavis`.`message` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'A PK of the table.',
`from` INT UNSIGNED NOT NULL COMMENT 'User that sent the message.',
`to` INT UNSIGNED NOT NULL COMMENT 'User that recieves the message.',
`text` VARCHAR(2000) NOT NULL COMMENT 'Text of the message. Length constrained in the frontend.',
`status` INT UNSIGNED NOT NULL DEFAULT 6 COMMENT 'Status of the message.',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Date and time when the message was created. Automaticaly recieves status 6 (draft).',
`viewed_at` DATETIME NULL COMMENT 'Date and time when the message was viewed by the reciever. Set when the status changes to 1.',
`sent_at` DATETIME NULL COMMENT 'Date and time when the message was sent. Set when the status changes to 2.',
`replied_at` DATETIME NULL COMMENT 'Date and time when the message was replied, if any. Set when the status changes to 3.',
`shared_at` DATETIME NULL COMMENT 'Date and time when the message was shared to external board. Set when the status changes to 4.',
`deleted_at` DATETIME NULL COMMENT 'Date and time of message deletion (from the view). Set when the status changes to 5.',
`message_type` INT UNSIGNED NOT NULL COMMENT 'Link to the type of the message.',
`attachment` INT UNSIGNED NULL COMMENT 'Link to the attachment.',
`template` INT UNSIGNED NULL COMMENT 'Link to the template the message implements.',
PRIMARY KEY (`id`),
INDEX `fk_user_from_idx` (`from` ASC),
INDEX `fk_user_to_idx` (`to` ASC),
INDEX `fk_message_type_type_idx` (`message_type` ASC),
INDEX `fk_message_status_status_idx` (`status` ASC),
INDEX `fk_message_attachment_idx` (`attachment` ASC),
INDEX `fk_message_template_idx` (`template` ASC),
CONSTRAINT `fk_user_from`
FOREIGN KEY (`from`)
REFERENCES `visavis`.`user` (`id`)
ON DELETE CASCADE
ON UPDATE NO ACTION,
CONSTRAINT `fk_user_to`
FOREIGN KEY (`to`)
REFERENCES `visavis`.`user` (`id`)
ON DELETE CASCADE
ON UPDATE NO ACTION,
CONSTRAINT `fk_message_type_type`
FOREIGN KEY (`message_type`)
REFERENCES `visavis`.`message_type` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION,
CONSTRAINT `fk_message_status_status`
FOREIGN KEY (`status`)
REFERENCES `visavis`.`message_status` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION,
CONSTRAINT `fk_message_attachment`
FOREIGN KEY (`attachment`)
REFERENCES `visavis`.`attachment` (`id`)
ON DELETE SET NULL
ON UPDATE NO ACTION,
CONSTRAINT `fk_message_template`
FOREIGN KEY (`template`)
REFERENCES `visavis`.`message_template` (`id`)
ON DELETE SET NULL
ON UPDATE NO ACTION)
ENGINE = InnoDB
COMMENT = 'Internal messaging system.'
CREATE TABLE IF NOT EXISTS `visavis`.`architect_counter` (
`architect` INT UNSIGNED NOT NULL COMMENT 'A PK of the table.',
`houses` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'The number of houses in the system.',
`followers` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'The number of followers.',
`liked_houses` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'The number of houses that the users liked.',
`sold` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'The number of purchased items of the architect.',
`messages` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'The number of unread messages.',
`customizings` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'The number of customize request an architect has received.',
`workings` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'The number of customizing work an archotect has begun work on. (accepted and assigned quotes)',
PRIMARY KEY (`architect`),
CONSTRAINT `fk_architect_counter_architect`
FOREIGN KEY (`architect`)
REFERENCES `visavis`.`architect` (`id`)
ON DELETE CASCADE
ON UPDATE NO ACTION)
ENGINE = InnoDB
COMMENT = 'Counter table for summed values, of the logged in achitect, ' /* comment truncated */ /*needed for the front end.*/
I also tried COALESCE(), CASE, read that IFNULL() returns SIGNED values so I CAST() the entire IFNULL clause.
I don't have any problem with delimiters (Workbench handles them)
THIS IS THE FIX:
IF EXISTS (SELECT 1 FROM `visavis`.`architect` WHERE `visavis`.`architect`.`user` = NEW.`to`)
THEN
SELECT `visavis`.`architect`.`id`
INTO archid
FROM `visavis`.`architect`
WHERE `visavis`.`architect`.`user` = NEW.`to`;
ELSE
SET archid = 0;
END IF;
I may be off track here, but this query
SELECT IFNULL(`visavis`.`architect`.`id`,0)
INTO archid
FROM `visavis`.`architect`
WHERE `visavis`.`architect`.`user` = NEW.`to`;
will set archid to the value of visavis.architect.id in the result row of the select statement or 0 if that value in the result row is null - i.e. there is a null value for that id in visavis.architect.
So what happens if the select statement doesn't match any rows? Well there is no result row, so the IFNULL statement is never run and archid remains at it's initial value of null.
I would remove the ifnull and let archid be set to null. Then just chnage your client/architect check to test if archid is null:
SELECT `visavis`.`architect`.`id`
INTO archid
FROM `visavis`.`architect`
WHERE `visavis`.`architect`.`user` = NEW.`to`;
IF NEW.status = 1
THEN
IF ISNULL(archid) THEN -- if the receiver is client
...
I am trying to learn foreign key constraint so far i have been able to create foreign keys in mysql
Here is my create table query for three tables:
create table customer(
CustId int(100) not null AUTO_INCREMENT primary key,
FirstName varchar(300) default null,
LastName varchar(300) default null,
Gender varchar(200) default null,
Category varchar(200) default null,
DateOfBirth varchar(200) default null,
Age int(3)default null
);
create table address(
Address_Id int(100) not null AUTO_INCREMENT primary key,
Address varchar(1000) default null,
Country varchar(500) default null,
State varchar (500) default null,
city varchar(500)default null,
PinCode int(10)default null,
CustId int(100) not null,
foreign key(CustId) references customer(CustId)
);
create table contact(
Contact_Id int(100) not null AUTO_INCREMENT primary key,
EmailId varchar(500)default null,
ContactNo varchar(20) default null,
MobileNo varchar(20) default null,
CustId int(100) not null,
Address_Id int(100) not null,
foreign key(CustId) references customer(CustId),
foreign key(Address_Id) references address(Address_Id)
);
K now i got it till here :
START TRANSACTION;
SET #lid := null;
insert into customer (FirstName,LastName,Gender,Category,DateOfBirth,Age)values('Ashok','sharma','Male','Affiliate','1988-04-17','26');
SELECT LAST_INSERT_ID() INTO #lid;
insert into address(CustId, Address,Country,State,city,Pincode)values (#lid, 'No.1645','India','Karnataka','Bangalore','560060');
COMMIT;
Using transaction and commit was the solution but how to do it for contact table where i have too foreign keys. And i need to get two auto incremented values.
Please guide me on this as well.
You do this in multiple statements:
START TRANSACTION;
SET #lid := null;
insert into customer (FirstName,LastName,Gender,Category,DateOfBirth,Age)values('Ashok','sharma','Male','Affiliate','1988-04-17','26');
SELECT LAST_INSERT_ID() INTO #lid;
insert into address(CustId, Address,Country,State,city,Pincode)values (#lid, 'No.1645','India','Karnataka','Bangalore','560060');
COMMIT;
For MySQL 5.1.12 and later, with no argument, LAST_INSERT_ID() returns a 64-bit value representing the first automatically generated value successfully inserted for an AUTO_INCREMENT column as a result of the most recently executed INSERT statement.
This is session bound, so don't worry, that another session messes up your last_insert_id or something. Read more about it here.
And you better put it all in a transaction like I did. This makes sure, that all statements succeed or none, not just parts of them. You have to use InnoDB for it though. MyISAM does not support this. Or you live with the risk :) But since you use foreign keys I assume you use InnoDB, just wanted to mention it for completeness.
The variable I used can of course be replaced with a PHP variable. Or you do it like this:
START TRANSACTION;
insert into customer (FirstName,LastName,Gender,Category,DateOfBirth,Age)values('Ashok','sharma','Male','Affiliate','1988-04-17','26');
SELECT LAST_INSERT_ID() INTO #lid;
insert into address(CustId, Address,Country,State,city,Pincode)
SELECT #lid, 'No.1645','India','Karnataka','Bangalore','560060';
COMMIT;
EDIT:
START TRANSACTION;
SET #lid_c := null;
SET #lid_a := null;
insert into customer (FirstName,LastName,Gender,Category,DateOfBirth,Age)values('Ashok','sharma','Male','Affiliate','1988-04-17','26');
SELECT LAST_INSERT_ID() INTO #lid_c;
insert into address(CustId, Address,Country,State,city,Pincode)values (#lid, 'No.1645','India','Karnataka','Bangalore','560060');
SELECT LAST_INSERT_ID() INTO #lid_a;
INSERT INTO contact (CustId, Address_Id, another_column) VALUES
(#lid_c, #lid_a, 'another_value');
COMMIT;
Help me please!
I am having this error.
Error: Cannot add or update a child row: a foreign key constraint fails (world.alarmes, CONSTRAINT fk_alarmes_registos1 FOREIGN KEY (idRegisto) REFERENCES registos (idRegisto) ON DELETE NO ACTION ON UPDATE NO ACTION)
I have these tables.
CREATE TABLE `registos` (
`data_registo` char(10) NOT NULL,
`hora_registo` time NOT NULL,
`idSensor` varchar(8) NOT NULL,
`Temperatura` char(6) DEFAULT NULL,
`Humidade` char(6) DEFAULT NULL,
`pt_orvalho` char(6) DEFAULT NULL,
`idRegisto` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`idRegisto`,`idSensor`,`data_registo`,`hora_registo`),
KEY `fk_registos_sensores1_idx` (`idSensor`),
CONSTRAINT `fk_registos_sensores1` FOREIGN KEY (`idSensor`) REFERENCES `sensores` (`idSensor`) ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE TABLE `alarmes` (
`idAlarme` int(11) NOT NULL AUTO_INCREMENT,
`descricao_alarme` varchar(45) DEFAULT NULL,
`data_criacao` datetime DEFAULT CURRENT_TIMESTAMP,
`idRegisto` int(11) NOT NULL DEFAULT ''0'',
PRIMARY KEY (`idAlarme`,`idRegisto`),
KEY `fk_alarmes_registos1_idx` (`idRegisto`),
CONSTRAINT `fk_alarmes_registos1` FOREIGN KEY (`idRegisto`) REFERENCES `registos` (`idRegisto`) ON DELETE NO ACTION ON UPDATE NO ACTION
)
When I do an insert into the table records the error pops up.
insert into registos values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9', '32');
If I do this:
SET FOREIGN_KEY_CHECKS=0
the next insertion already accepted, but when I try again. back to give the same error.
I've been researching and fails because the registos table references a foreign key from the sensores table. You can't directly insert into a relational table without there being a corresponding entry in the table that is being referenced.
But I don't know how to resolve this.
Help me please.
-------EDIT( I used a trigger to populate the table Alarmes)------------------------
DELIMITER $$
create TRIGGER alerta
BEFORE INSERT ON registos
FOR EACH ROW
begin
Set #tempmax=0;
Set #tempmin=0;
select lim_inf_temp, lim_sup_temp into #tempmin, #tempmax from sensores where idSensor=NEW.idSensor;
Set #maxidAlarme=0;
if (CAST(NEW.Temperatura AS UNSIGNED)<#tempmin) then
SELECT MAX(idAlarme) into #maxidAlarme FROM alarmes;
SET #maxidAlarme=#maxidAlarme+1;
INSERT INTO alarmes(idAlarme,descricao_alarme, idRegisto) VALUES (#maxidAlarme,"temperatura inserida inferior ao normal",New.idRegisto);
end if;
if (CAST(NEW.Temperatura AS UNSIGNED)>#tempmax) then
SELECT MAX(idAlarme) into #maxidAlarme FROM alarmes;
SET #maxidAlarme=#maxidAlarme+1;
INSERT INTO alarmes(idAlarme,descricao_alarme, idRegisto) VALUES (#maxidAlarme,"temperatura inserida superior ao normal",New.idRegisto);
end if;
end $$;
DELIMITER ;
You are trying to insert more values into the table than allowed 7 (seven) but 6 (six) expected.
Please, always include the columns that you are inserting to in an 'insert' query.
There are seven columns in this table but one is an 'auto increment' column so there should be 6 (six) values in the insert query.
CREATE TABLE `registos` (
`data_registo` char(10) NOT NULL,
`hora_registo` time NOT NULL,
`idSensor` varchar(8) NOT NULL,
`Temperatura` char(6) DEFAULT NULL,
`Humidade` char(6) DEFAULT NULL,
`pt_orvalho` char(6) DEFAULT NULL,
`idRegisto` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`idRegisto`,`idSensor`,`data_registo`,`hora_registo`),
KEY `fk_registos_sensores1_idx` (`idSensor`),
CONSTRAINT `fk_registos_sensores1
Here is the 'insert' query:
insert into registos values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9', '32');
There are seven values but you would expect the query to look like (columns added):
insert into registos (data_registo, hora_registo, idSensor, Temperatura, Humidade, pt_orvalho)
values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9', '32');
I suggest that the query should be:
insert into registos (data_registo, hora_registo, idSensor, Temperatura, Humidade, pt_orvalho)
values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9');
The trigger on 'registos' must be an after insert trigger to pick up the NEW 'idRegisto' value.
create TRIGGER alerta
AFTER INSERT ON registos
FOR EACH ROW
begin
I Want to add an Integer Column to a String that's because i need to generate a varchar variable with a numeric part that automatically increments. For example, P000001,P000002...
In order to do that what i am doing while creation of table i have taken an int field ID which auto_increments and i am Concatenating P with 00000 and the ID value
The Table i have created is :
CREATE TABLE tblAcceptTest(
ID int AUTO_INCREMENT NOT NULL primary key,
PatientID as CONCAT('P' , CONCAT('000000',CAST(ID as char)))
);
It Shows me the error from as keyword.
Please help
MySQL's documentation (http://dev.mysql.com/doc/refman/5.1/en/create-table.html) says, "the default value must be a constant; it cannot be a function or an expression." Why don't you just get the PatientID value afterward as part of the SELECT:
SELECT CONCAT('P', LPAD(ID, 6, 0)) AS PatientID FROM tblAcceptTest;
It looks like you want six digits after the "P", so try this for your expression:
CONCAT('P', LPAD(ID, 6, '0'))
Mysql has little support for computed columns.
Patient ID from your specification could be a char(7)
CREATE TABLE tblAcceptTest(
ID int AUTO_INCREMENT NOT NULL primary key,
PatientID char(7)
);
Then create some triggers. Note that the following insert trigger will cause issues with high concurrency servers.
DELIMITER |
CREATE TRIGGER tblAcceptTest_insert BEFORE INSERT ON tblAcceptTest
FOR EACH ROW BEGIN
DECLARE next_id INT;
SET next_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='tblAcceptTest');
SET NEW.PatientID = CONCAT('P' , RIGHT(CONCAT('000000',next_id),6)) ;
END;
|
CREATE TRIGGER tblAcceptTest_update BEFORE UPDATE ON tblAcceptTest
FOR EACH ROW BEGIN
SET NEW.PatientID = CONCAT('P' , RIGHT(CONCAT('000000',NEW.ID),6)) ;
END;
|
DELIMITER ;
You use relationships and views to achieve the same result.
CREATE TABLE `patient` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`patient` varchar(60) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `accepted_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`patient_id` int(11) NOT NULL,
`accepted` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `patient_id` (`patient_id`),
CONSTRAINT `accepted_test_ibfk_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create or replace view accepted_test_veiw as
select CONCAT('P' , RIGHT(CONCAT('000000',patient_id),6)) patient_key
, accepted
, id accepted_test_id
, patient_id
from accepted_test ;
select * from `accepted_test_veiw`