Mysql trigger on Delete to multiple tables (also error 1235) - mysql

I have 3 tables that are called:
character_
learned_skills
skills
"character_" contains certain informations on a list of characters, while the table "skills" contrains a list of skills.
the 3rd table is the list of the skills each character has learned.
However I want to able ones a character has been deleted from the character_ table, it also deletes the name of that character and the skills it has learned from the table "learned_skills".
I assume that a trigger is required in this situation. I know that the syntax is:
CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR REACH ROW tigger_statement;
However I can't figure out how the trigger_statement should look like.
CREATE TRIGGER delete_char_ AFTER DELETE ON character_ FOR REACH ROW trigger_statement
Is it enough with a sigle statement or does it require several statements and or cascade?
What would you do in this situation?
CREATE TABLE character_ (
Name_ varchar (30) NOT NULL,
Class varchar (30),
World_Type varchar (15),
Str integer ,
WS integer ,
BS integer ,
Fel integer ,
Per integer ,
Int_ integer ,
Agi integer ,
WP integer ,
Tough integer ,
PRIMARY KEY (Name_) ,
FOREIGN KEY (Class) REFERENCES Class(Class_name),
FOREIGN KEY (World_Type) REFERENCES World_Type(Name_) );
CREATE TABLE Skills (
SkillName varchar (30) NOT NULL,
Type_ varchar (30),
Characteristic varchar (30),
Descriptor varchar (30),
PRIMARY KEY (SkillName) );
CREATE TABLE Learned_Skills (
Character_Name varchar (30) NOT NULL,
Skill_Name varchar (40) NOT NULL,
PRIMARY KEY (Character_Name,Skill_Name),
FOREIGN KEY (Character_Name) REFERENCES character_(Name_),
FOREIGN KEY (Skill_Name) REFERENCES Talents(TalentName) );
UPDATE:
So I have had help to understand and make a DELETE trigger, but I have found out that need to create a multiple trigger on two tables, I know that its not possible to create a trigger on two with the same triggertime and event, but is there a way around it? What I need is the following:
DELIMITER //
CREATE TRIGGER delete_char_ AFTER DELETE ON character_
FOR EACH ROW begin
DELETE FROM learned_skills
WHERE learned_skills.Character_Name = old.Name_;
DELETE FROM learned_talents
WHERE learned_talents.Character_Name = old.Name_;
END;
//
DELIMITER ;
When I run this code I get error code:
1235, this version of mysql doesn't yet support 'multiple triggers with the samme action time and event for one table

Here is what it would look like:
CREATE TRIGGER delete_char_ AFTER DELETE ON character_
FOR EACH ROW
DELETE FROM learned_skills
WHERE learned_skills.Character_Name = old.Name_;
You will need to replace <field> with whatever the primary key is of the character_. This will delete anything from the learned_skills table that has the <field> of the character_ being deleted.

Related

Syntax error unexpected ON

DELIMITER $$
SET TERMOUT ON
PROMPT Building Tutorial System. Please wait.
-- SET TERMOUT OFF
-- Drop Tables
DROP TABLE Enrollment CASCADE CONSTRAINTS;
DROP TABLE Attendance;
DROP TABLE Student CASCADE CONSTRAINTS;
DROP TABLE Tutorial CASCADE CONSTRAINTS;
-- Create Tables
CREATE TABLE Student(
id NUMBER(10) PRIMARY KEY NOT NULL,
name VARCHAR(255)
);
CREATE TABLE Tutorial(
id NUMBER(10) PRIMARY KEY NOT NULL,
name VARCHAR(255),
tutor VARCHAR(255),
room VARCHAR(255),
day NUMBER(10),
time DATE,
end_date_of_tutorial DATE,
type NUMBER(1)
);
CREATE TABLE Enrollment(
id NUMBER(10) PRIMARY KEY NOT NULL,
student_id NUMBER(10),
tutorial_id NUMBER(10),
enrollment_date_of_tutorial DATE,
FOREIGN KEY(student_id) REFERENCES Student(id),
FOREIGN KEY(tutorial_id) REFERENCES Tutorial(id)
);
CREATE TABLE Attendance(
enrollment_id NUMBER(10),
att_date DATE,
attendance CHAR(1),
FOREIGN KEY(enrollment_id) REFERENCES Enrollment(id)
);
I am getting red errors marks in MySQL workbench source code editor on line 1 "SET TERMOUT ON" Syntax error unexpected ON been trying to resolve this issue however no progress so if someone could help me out.
First of all, the correct SET syntax is
SET var = value
See http://dev.mysql.com/doc/refman/5.7/en/set-statement.html
Also, with the SET command you can either change a system variable or initialize a user variable. AFAIK TERMOUT is not a system variable so you should use:
SET #TERMOUT = ON
Finally, I am not sure that "ON" is a valid value for a user variable so you probably should use
SET #TERMOUT = 1

Oracle DB - Primary Key Auto Increment Column without Sequence

I wonder if there is a way to create a table column with an primary key which is auto incremented without using a sequence.
I saw that it was working by using IDENTITY on Microsofts SQL Server and AUTO_INCREMENT on MySQL, but cannot get something that works with Oracle DB.
This is my current approach:
CREATE TABLE test
( id NUMBER(6) IDENTITY,
CONSTRAINT pk_id PRIMARY KEY (id)
)
Identity columns in Oracle would meet your requirement, but they were introduced in Oracle Database 12c.
Since you are on Oracle Database 11g, the best approach would be to use a sequence + trigger approach. Tim Hall has a good write up of this here:
Excerpt:
Create a table with a suitable primary key column and a sequence to
support it.
CREATE TABLE departments (
ID NUMBER(10) NOT NULL,
DESCRIPTION VARCHAR2(50) NOT NULL);
ALTER TABLE departments ADD (
CONSTRAINT dept_pk PRIMARY KEY (ID));
CREATE SEQUENCE dept_seq;
Create a trigger to populate the ID column if it's not specified in
the insert.
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON departments
FOR EACH ROW
WHEN (new.id IS NULL)
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;

MySQL if exists update else create new

I have a vet table and a medical table with a 1 to many relationship, and the ID's are auto incremented.
CREATE TABLE vet(
vetID INT NOT NULL AUTO_INCREMENT,
vetPractice varchar(35),
Address varchar(150),
contactNumber varchar (15),
PRIMARY KEY (VetID)
);
CREATE TABLE medical(
medicalID INT NOT NULL AUTO_INCREMENT,
medication VARCHAR (200),
PRIMARY KEY (medicalID),
FOREIGN KEY (vetID) REFERENCES vet(vetID)
);
Users can enter details of a vet, i want a query to determine;
if the the vet details entered already exist, then update the foreign key in vetID(medical) with the entered vetID.
else if the vet does not exist create a new vet and update the foreign key in vetID(medical) with the newly created vetID.
You want to do an upsert in MySql. I think that this link can be helpful.
Example:
INSERT INTO table (x,x,x) VALUES (x,x,x)
ON DUPLICATE KEY UPDATE x=x+x;
You have to do a "select" query to determine whether exists .
Select medicalID from medical where medication=?
This should be executed in a different query as the update , you need to use server language to see if the results brings back a result.Then using an "if" statement determine your routine.
hope this helps.

MYSQL doesn't check for Foreign key exsistence

I am facing a strange problem here.
TABLE 1:
create table degree (degree_id varchar(6) primary key , degree_name varchar(32) unique key , degree_abbr varchar(3));
TABLE 2:
create table course (course_id varchar(6) primary key , degree_id varchar(6) not null, course_name varchar(40) not null , foreign key (degree_id) references degree
(degree_id));
Now as far as I understand SQL , I cannot insert any value in the course table if the value of field degree_id doesn't exist in the degree table.
But if I try to insert something like
insert into course values('cor_001' , 'blah' , 'COURSE NAME' );
This query runs successfully , even though 'blah' is not a valid degree_id.
You're probably using MyISAM tables, which do NOT support foreign keys. The FK directives are parsed and accepted, then ignored.
You need to use InnoDB tables for proper FK support:
CREATE TABLE (...) ENGINE=InnoDB;
^^^^^^^^^^^^^^
If you do a show create table your_table, you'll see the engine type being used at the end of the output.

Need comments on MySQL events

SET GLOBAL event_scheduler = ON;
CREATE TABLE question(
qid INT AUTO_INCREMENT PRIMARY KEY,
name CHAR(30) NOT NULL,
text CHAR(100) NOT NULL,
variation BOOLEAN NOT NULL,
url CHAR(100) NOT NULL UNIQUE,
expired TIMESTAMP NOT NULL
);
CREATE TABLE alternativ(
aid INT AUTO_INCREMENT PRIMARY KEY,
name CHAR(30) NOT NULL,
text CHAR(50) NOT NULL,
number_chosen INT,
qid INT NOT NULL
);
ALTER TABLE alternativ
ADD FOREIGN KEY (qid)
REFERENCES question(qid);
CREATE EVENT delete_expired
ON SCHEDULE
EVERY 1 DAY
DO
DELETE FROM alternativ WHERE alternativ.qid IN (SELECT qid FROM question WHERE question.expired<CURRENT_TIMESTAMP)
DELETE FROM question WHERE question.expired < CURRENT_TIMESTAMP;
My question is: Should this event work with the specified database? I have tried, but it dosen't seem to work. The idea is that the database itself will delete questions that has expired. Help would much be appreciated.
If you want to specify multiple statements within the event body, you will need to wrap them within a compound statement block such as BEGIN ... END (in order to make such a command work, one must configure one's client to use an alternative statement delimiter in order that it does not think the first encountered semicolon terminates the CREATE EVENT statement—in the mysql command-line tool, one can use the DELIMITER command):
DELIMITER ;;
CREATE EVENT ... DO BEGIN
DELETE ... ;
DELETE ... ;
END ;;
DELIMITER ;
That said, one can delete from multiple tables with a single DELETE command using the multiple-table syntax:
DELETE alternativ, question
FROM alternativ JOIN question USING (qid)
WHERE question.expired < CURRENT_TIMESTAMP
However, all that said, you might fare better specifying foreign key constraints that cascade record deletions:
FOREIGN KEY (qid) REFERENCES question(qid) ON DELETE CASCADE
Then, one only need DELETE the referenced record (i.e. in the question table) and MySQL will delete the referencing records (i.e. in the alternativ table) for you.