Mysql with function - mysql

CREATE TABLE `emp_info` (
id INT NOT NULL AUTO_INCREMENT,
user_id INT,
first_name VARCHAR(70),
last_name VARCHAR(70),
PRIMARY KEY (id),
KEY (user_id)
);
CREATE TABLE `message_info` (
id INT NOT NULL AUTO_INCREMENT,
user_id INT,
message MEDIUMTEXT,
PRIMARY KEY (id),
CONSTRAINT fk_message FOREIGN KEY(user_id) REFERENCES emp_info(user_id)
);
INSERT INTO emp_info(user_id,first_name,last_name) VALUES
(001,'Ashley','Smith'),
(002,'Valen','Hue'),
(003,'Mia','Cmd'),
(004,'Alex','Smith'),
(005,'Dy','Thomson'),
(006,'Ashley','Smith'),
(007,'Alex','Smith'),
(008,'Dy','Thomson');
INSERT INTO message_info(message) VALUES
('This is a message1 '),
('This is a message2'),
('This is not messge3'),
('This is a messagee4'),
('This is a messge5');
Hi, all I need mini help with the function.
Create a function with parameters of id user to count and return the total number of messages he/she has sent.

if we are talking about a specific id, the query is like:
SELECT count(*) FROM message_info where message_info.user_id = ´your_id´
To create a function is like:
DELIMETER $$
CREATE FUNCTION count_message(id INT)
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE count_message INT;
select count(*) INTO count_message FROM message_info where message_info.user_id = ´your_id´;
return count_message;
END$$
DELIMITER ;
in you query insert you are missing the id user, so you need add it.

Related

Please, can someone help me to create a trigger in mysql that has a same function with the assertion below?

So basically I want to create a trigger for mysql database that has same/similar function with the assertion code below (since mysql does not support assertion)
Here is the assertion code that I want to replicate using trigger
CREATE ASSERTION assert
CHECK NOT EXISTS(SELECT * FROM paper P WHERE 3 <>(SELECT COUNT(*)
FROM review R
WHERE R.paperid = P.paperid)
);
CREATE ASSERTION atmostfivepapers
CHECK NOT EXISTS(SELECT * FROM pcmember P WHERE 5 <
( SELECT *
FROM review R
WHERE R.email = P.email
)
);
And here is my table
CREATE TABLE paper(
paperid INT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(50) NOT NULL,
abstract VARCHAR(250),
pdf VARCHAR(100),
PRIMARY KEY(paperid)
);
CREATE TABLE author(
email VARCHAR(100) NOT NULL,
name VARCHAR(50),
affiliation VARCHAR(100),
PRIMARY KEY(email)
);
CREATE TABLE writePaper(
paperid INT UNSIGNED NOT NULL AUTO_INCREMENT,
email VARCHAR(100),
paper_order INT,
PRIMARY KEY(paperid, email),
FOREIGN KEY(paperid) REFERENCES paper(paperid),
FOREIGN KEY(email) REFERENCES author(email)
);
CREATE TABLE pcmember(
email VARCHAR(100) NOT NULL,
name VARCHAR(20),
PRIMARY KEY(email)
);
CREATE TABLE review(
reportid INT UNSIGNED,
sdate DATE,
comment VARCHAR(250),
recommendation CHAR(1),
paperid INT UNSIGNED,
email VARCHAR(100),
PRIMARY KEY(paperid, email),
FOREIGN KEY(paperid) REFERENCES paper(paperid),
FOREIGN KEY(email) REFERENCES pcmember(email)
);
Thanks in advance
First create another table replicating the columns and their features. Thereafter create a trigger.
CREATE TRIGGER afterInsert_trigger on yourMainTableName
FOR INSERT
AS
INSERT INTO yourTableCopy(column1ofYourReplicateTable, column2OFyourReplicateTable, ... etc)
SELECT column1ofYourMainTable, column2ofYourMainTable, ..., etc
FROM INSERTED
That's what I use in Microsoft SQL server

MySql assigning a select

I am trying to create a MySql function that will tell me how many orders(comanda) have been placed by a client(whose id i will provide as a parameter).
However, I am getting a syntax error that says counter(my decared variable) is not valid at this position, expecting an identifier.
I split the declaration and both assignments of the value just to be sure that this is not the reason for the error. The error triggers at the last assignment of the select.
Can anybody explain what I am doing wrong? Thank you!
create table client
(id int primary key auto_increment,
nume varchar(50),
prenume varchar(50),
oras varchar(50),
judet varchar(50),
strada varchar(50),
cod_postal varchar(50),
nr_tel varchar(50),
email varchar(50)
);
create table comanda
(id int primary key auto_increment,
data_plasare date,
metoda_livrare enum('ridicare personala','livrare la domiciliu','easy box'),
metoda_plata enum('numerar','card la ghiseu','online cu cardul','transfer bancar','PayPal','rate'),
id_client int
);
alter table comanda
add foreign key (id_client) references client(id);
delimiter //
create function clienti_multiple_comenzi(p_id_client int)
returns int
begin
declare counter int;
set counter = 0;
set counter = select count(id)
from comanda
where id_client = p_id_client;
return counter;
end;
// delimiter ;

MySQL trigger to target an attribute of a column

I am working with an overlap super/subtype relationship dealing with person(s) in my DB. What I would like to do is have the overlapping subtypes insert new rows when the supertype gains a new row. I have attached my LRD to clarify the relationship. LRD
I would like to create a trigger that inserts new person rows into the correct subtype based on the attributes employee/user in the person table.
The code I have attempted so far gives me an error upon inserting rows into person noting "employee column does not exist". I would assume this is because this code is trying to use the if statement for the subtypes where it is in fact absent.
I would appreciate any feedback.
Table Details
CREATE TABLE PERSON
(person_id int(10) not null AUTO_INCREMENT,
first_name varchar(15) not null,
last_name varchar(15) not null,
employee char(1),
participant char(1),
CONSTRAINT person_pk PRIMARY KEY (person_id))
ENGINE=InnoDB;
CREATE TABLE EMPLOYEE
(eperson_id int(10) not null AUTO_INCREMENT,
enterprise_email varchar(30),
manager_id int(10),
CONSTRAINT employee_pk PRIMARY KEY (eperson_id),
CONSTRAINT employee_fk1 FOREIGN KEY(eperson_id) REFERENCES PERSON(person_id) ON update cascade,
CONSTRAINT employee_fk2 FOREIGN KEY(manager_id) REFERENCES EMPLOYEE(eperson_id) ON update cascade)
ENGINE=InnoDB;
CREATE TABLE PARTICIPANT
(pperson_id int(10) not null AUTO_INCREMENT,
city varchar(30),
state varchar(2),
zip int(5),
sign_up_date date,
termination_date date,
CONSTRAINT participant_pk PRIMARY KEY (pperson_id),
CONSTRAINT participant_fk FOREIGN KEY(pperson_id) REFERENCES PERSON(person_id) ON update cascade)
ENGINE=InnoDB;
Trigger Code
DELIMITER //
CREATE TRIGGER subtype_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (employee = ‘e’ ) THEN
INSERT INTO EMPLOYEE
SET eperson_id = NEW.person_id,
last_name = NEW.last_name,
enterprise_email = NULL,
manager_id = NULL;
IF (participant = ‘p’ )THEN
INSERT INTO PARTICIPANT
SET pperson_id = NEW.person_id,
city=NULL,
state = NULL,
zip = NULL,
sign_up_date =NULL,
termination_date = NULL;
END IF;
END IF;
END//
DELIMITER ;
This may work for you.
First off, I think to have the AUTO_INCREMENT attribute on columns EMPLOYEE.eperson_id and PARTICIPANT.pperson_id is not needed.
Since both of those columns are FOREIGN KEYS and are referencing back to the person_id column of table PERSON, they need to have, and will be getting, their values from that column through the TRIGGER anyway so no need to autoincrement them in the tables.
So I would change that.
This TRIGGER should work with populating both tables EMPLOYEE and PARTICIPANT after INSERT on table PERSON:
DELIMITER //
CREATE TRIGGER subtype_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
INSERT INTO EMPLOYEE(eperson_id, enterprise_email, manager_id)
VALUES(NEW.person_id, NULL, NULL);
INSERT INTO PARTICIPANT(pperson_id, city, state, zip, sign_up_date, termination_date)
VALUES(NEW.person_id, NULL, NULL, NULL, NULL, NULL);
END//
DELIMITER ;
Hope this helps you.
I ended up figuring out two methods to solve my issue. I ended up altering my 'employee' and 'participant' into boolean/tinyint data types.
CREATE TABLE PERSON
(person_id int(10) not null AUTO_INCREMENT,
first_name varchar(15) not null,
last_name varchar(15) not null,
employee tinyint(1),
participant tinyint(1),
CONSTRAINT person_pk PRIMARY KEY (person_id))
ENGINE=InnoDB;
After that alteration I decided to try and break up the one trigger into two. This was successful.
Type 1
DELIMITER //
CREATE TRIGGER employee_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (NEW.employee = 1 ) THEN
INSERT INTO EMPLOYEE
SET eperson_id = NEW.person_id,
last_name = NEW.last_name,
enterprise_email = NULL,
manager_id = NULL;
END IF;
END//
DELIMITER ;
DELIMITER //
CREATE TRIGGER participant_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (NEW.participant =0 )THEN
INSERT INTO PARTICIPANT
SET pperson_id = NEW.person_id,
city=NULL,
state = NULL,
zip = NULL,
sign_up_date =NULL,
termination_date = NULL;
END IF;
END//
DELIMITER ;
After inplementing that first option I realized the ELSEIF would allow me to not split the two and create a single trigger.
Type 2
DELIMITER //
CREATE TRIGGER employee_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (NEW.employee = 1 ) THEN
INSERT INTO EMPLOYEE
SET eperson_id = NEW.person_id,
last_name = NEW.last_name,
enterprise_email = NULL,
manager_id = NULL;
ELSEIF (NEW.participant =0 )THEN
INSERT INTO PARTICIPANT
SET pperson_id = NEW.person_id,
city=NULL,
state = NULL,
zip = NULL,
sign_up_date =NULL,
termination_date = NULL;
END IF;
END//
DELIMITER ;

Stored procedure to select column from table and insert to multiple table in mysql

I want to select values from basic2 and insert into basic3 and basic4 using stored procedure.
These are the table definitions:
create table basic2(
id int AUTO_INCREMENT,
name varchar(50),
address varchar(50),
PRIMARY KEY (id)
);
create table basic3(
id int AUTO_INCREMENT,
name varchar(50),
address varchar(50),
PRIMARY KEY (id)
);
create table basic4(
id int AUTO_INCREMENT,
name varchar(50),
address varchar(50),
PRIMARY KEY (id)
);
this is the new_person store procedure
drop procedure if exists new_person;
DELIMITER //
CREATE PROCEDURE new_person
select (id, name,address)
from basic2;
BEGIN
START TRANSACTION;
INSERT INTO basic3 (id,name,address)
VALUES(LAST_INSERT_ID(),bname,baddress);
INSERT INTO basic4 (id,name,address)
VALUES(LAST_INSERT_ID(),bname,baddress);
COMMIT;
END//
DELIMITER;
We can do it by two way one for using cursor and another is using SELECT with insert i thing for you SELECT is better
Like this
INSERT INTO basic3 (name,address)
SELECT name, address FROM basic2;

inserting values from arrays in mysql

I have multiple user_roles. Each user_role has multiple privileges and each privileges has multiple values. I need to create a procedure with user_role_name,description,priviliges_fk(array),values(arrayofstring) as inputs.
This is the procedure I have written.
DELIMITER $$
DROP PROCEDURE IF EXISTS `save_role`$$
CREATE DEFINER=`event_admin`#`%` PROCEDURE `save_role`(IN p_role_name INT,
IN p_description INT,
IN p_privilege_fk INT(),
IN p_values VARCHAR(1000)
)
BEGIN
DECLARE i int default 0;
DECLARE V_ROLE_FK int;
DECLARE counter INT DEFAULT 0;
INSERT INTO ROLE (ROLE_NAME,DESCRIPTION) VALUES(p_role_name,p_description);
SELECT ROLE_PK INTO V_ROLE_FK FROM ROLE WHERE ROLE_NAME=p_role_name AND DESCRIPTION=p_description;
simple_loop:LOOP
SET counter = counter + 1;
INSERT INTO ROLE_PRIVILEGE_BRIDGE (ROLE_FK,PRIVILEGE_FK,VALUE) VALUES(V_ROLE_FK,p_privilege_fk(i),p_values);
END LOOP simple_loop;
END;
You can't. There are two workarounds that would work
Call the procedure one time per element in the array
Concatenate the array elements into one string separated by something (ie |, ;, :) and then split that string internally in the procedure.
I would go with the first alternative. It's cleaner, easier to understand and easier to test.
I'd suggest you to use AUTO_INCREMENT option for primary keys, it will help to work with them. Then use auto-incremented primary key values to insert new rows into a child table - one by one, not using array as a string parameter.
For example (data is simplified):
CREATE TABLE ROLE(
ID INT(11) NOT NULL AUTO_INCREMENT,
ROLE_NAME INT,
DESCRIPTION INT,
PRIMARY KEY (ID)
)
ENGINE = INNODB;
CREATE TABLE ROLE_PRIVILEGE_BRIDGE(
ID INT(11) NOT NULL AUTO_INCREMENT,
PRIVILEGE_FK INT(11) DEFAULT NULL,
VALUE INT(11) DEFAULT NULL,
PRIMARY KEY (ID),
CONSTRAINT FK FOREIGN KEY (PRIVILEGE_FK) REFERENCES ROLE (ID)
)
ENGINE = INNODB;
INSERT INTO ROLE(ROLE_NAME, DESCRIPTION) VALUES(1, 1);
SET #new_id = LAST_INSERT_ID();
INSERT INTO ROLE_PRIVILEGE_BRIDGE(PRIVILEGE_FK, VALUE) VALUES (#new_id, 1);
INSERT INTO ROLE_PRIVILEGE_BRIDGE(PRIVILEGE_FK, VALUE) VALUES (#new_id, 2);
INSERT INTO ROLE_PRIVILEGE_BRIDGE(PRIVILEGE_FK, VALUE) VALUES (#new_id, 3);