Advise the GUI tool for viewing dependent object database MySQL.
for example:
USE db;
CREATE TABLE t1(
id INT(11) NOT NULL,
`column` INT(11) DEFAULT NULL,
UNIQUE INDEX id (id)
);
CREATE TABLE t2(
id INT(11) NOT NULL,
`column` INT(11) DEFAULT NULL,
INDEX FK_t2_t1_id (`column`),
CONSTRAINT FK_t2_t1_id FOREIGN KEY (`column`)
REFERENCES t1 (id) ON DELETE RESTRICT ON UPDATE RESTRICT
);
CREATE TABLE t3(
id INT(11) NOT NULL,
`column` INT(11) DEFAULT NULL,
INDEX FK_t3_t1_id (`column`),
CONSTRAINT FK_t3_t1_id FOREIGN KEY (`column`)
REFERENCES t1 (id) ON DELETE RESTRICT ON UPDATE RESTRICT
);
DELIMITER $$
CREATE DEFINER = 'root'#'localhost'
PROCEDURE procedure1()
BEGIN
SELECT
*
FROM
db.t1;
END
$$
DELIMITER ;
I want to see which objects refer to the table t1.
In this example it are t2, t3 and procedure1
This is most likely what you are looking for. The information can be found in information_schema.
SELECT pk.constraint_schema AS PKDatabaseName
, pk.table_name AS PKObjectName
, fk_cols.column_name AS PKColumnName
, fk_cols.referenced_table_schema AS FKDatabaseName
, fk_cols.referenced_table_name AS FKObjectName
, fk_cols.referenced_column_name AS FKColumnName
, pk.constraint_name AS ConstraintName
, fk_cols.ordinal_position AS ColumnIdx
FROM information_schema.table_constraints pk
INNER JOIN information_schema.key_column_usage fk_cols
ON pk.constraint_schema = fk_cols.table_schema
AND pk.table_name = fk_cols.table_name
AND pk.constraint_name = fk_cols.constraint_name
WHERE pk.constraint_type = 'FOREIGN KEY'
Your question isn't all that clear, but it sounds like you're looking for some sort of GUI tool to do data modeling with MySQL. If that's correct, try looking at MySQL Workbench.
Related
Why the following error (Can't update table 'table_b' in stored function/trigger because it is already used by statement which invoked this stored function/trigger) appears after i try to delete with inner join?
Can i solve it?
DROP TABLE if exists table_b;
DROP TABLE if exists table_a;
CREATE TABLE table_a (
id int auto_increment,
name varchar(255) DEFAULT NULL,
primary key (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
DROP TABLE if exists table_b;
CREATE TABLE table_b (
id int auto_increment,
name varchar(255) DEFAULT NULL,
id_table_a int NOT null,
another_table_id int NOT null,
foreign key (id_table_a) references table_a(id),
primary key (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
DELIMITER $$
drop trigger if exists tg_test$$
create trigger tg_test before delete on table_a for each row
begin
delete from table_b where id_table_a = OLD.id;
end$$
DELIMITER ;
insert into table_a(name) values('t-a');
insert into table_b(name, id_table_a, another_table_id) values('t-b', 1, 23);
-- Error Can't update table 'table_b' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
-- in any of this two lines
delete table_a from table_a inner join table_b on table_b.id_table_a = table_a.id where another_table_id = 23;
delete from table_a where id in (select id_table_a from table_b where another_table_id = 23);
-- Success
delete from table_a where id = 1;
I don't see the point for a trigger here. The functionality you want can be achieved by just adding the on delete cascade option to the declaration of your foreign key:
CREATE TABLE table_b (
id int auto_increment,
name varchar(255) DEFAULT NULL,
id_table_a int NOT null,
another_table_id int NOT null,
foreign key (id_table_a) references table_a(id) on delete cascade,
primary key (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Now anytime a record is dropped from table_a, the children record (as designated by the foreign key definition) are deleted from table_b.
With this set-up (and without the trigger), both your delete statements would run fine. I would actually use exists rather than a join or in, but that's mostly a matter of taste:
delete from table_a
where exists(
select 1
from table_b b
where b.id_table_a = table_a.id and b.another_table_id = 23
);
In a MySQL database, I need to create a new closure table (called closure_new) that integrates a two column foreign key to another table, concept. This means adding rows to closure_new that are not in closure. How do I set up the SQL to accomplish this?
Here is my first attempt at the code for populating closure_new:
INSERT INTO `closure_new`
SELECT o.subtypeId, d.id, d.effectiveTime
FROM concept d
JOIN closure o
ON o.subtypeId = d.id;
Note that my first attempt only addresses subtypeId/subtype_effectiveTime and might not address it completely. The SQL also needs to incorporate supertypeId/supertype_effectiveTime. How do I write the SQL to populate the closure_new table with records for each of the effectiveTime values associated with each subtypeId and each supertypeId?
Here is the concept table:
CREATE TABLE `concept` (
`id` BIGINT NOT NULL DEFAULT 0,
`effectiveTime` VARCHAR(8) NOT NULL DEFAULT '',
`some other fields`,
PRIMARY KEY (`id`,`effectiveTime`)
) ENGINE=InnoDB;
Here is the old closure table:
CREATE TABLE `closure` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`subtypeId` BIGINT(20) NOT NULL ,
`supertypeId` BIGINT(20) NOT NULL ,
PRIMARY KEY (`id`)
);
Here is the closure_new table that needs to be populated with the script I started to write above:
CREATE TABLE `closure_new` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`subtypeId` BIGINT(20) NOT NULL ,
`subtype_effectiveTime` VARCHAR(8) NOT NULL DEFAULT '',
`supertypeId` BIGINT(20) NOT NULL ,
`supertype_effectiveTime` VARCHAR(8) NOT NULL DEFAULT '',
FOREIGN KEY (`supertypeId`, `supertype_effectiveTime`) references concept(`id`, `effectiveTime`),
FOREIGN KEY (`subtypeId`, `subtype_effectiveTime`) references concept(`id`, `effectiveTime`)
); ENGINE=InnoDB;
Try this:
insert into closure_new
(subtypeId, subtype_effectiveTime, supertypeId, supertype_effectiveTime)
select cl.id, co.effectiveTime, co.id, co.effectiveTime from closure cl inner join concept co
Your data better match or you will have some foreign key constraint issues
Not sure if I completely understand what you're after, but how about:
INSERT INTO `closure_new` (subtypeId, subtype_effectiveTime, supertypeId, supertype_effectiveTime)
SELECT subCon.id, subCon.effectiveTime, superCon.id, superCOn.effectiveTimed.effectiveTime
FROM closure o, concept subCon, concept superCon
where subcon.Id = o.subtypeId and supercon.Id = o.supertypeId
Or possibly, you could just create view with that select statement.
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`
Trigger actually. But how do i make this in mysql-workbench. So that anytime i have any new records in table1 it creates a new record referencing table1.id to table2.parentid ?
--- [OK] --- This is created
CREATE TABLE IF NOT EXISTS `test`.`table1` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB
--- [FAIL] --- #1005 - Can't create table 'test.table2' (errno: 150)
CREATE TABLE IF NOT EXISTS `test`.`table2` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
`parentid` VARCHAR(45) NULL ,
`table1_id` BIGINT(20) NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_table2_table1` (`parentid` ASC) ,
CONSTRAINT `fk_table2_table1`
FOREIGN KEY (`parentid` )
REFERENCES `test`.`table1` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
Follow up:
1) Mysql workbench do not offer that
2) Click the table1 > click the triggers tab bottom > write
-- trigger module initiate
DELIMITER $$
CREATE TRIGGER triggertest1 BEFORE INSERT ON table1
FOR EACH ROW BEGIN
INSERT INTO table2 SET parentid = NEW.id;
END;
$$
DELIMITER ; --- return to normal
Thats because you have different datatype of id column in your child table change it to BIGINT(20)
I'm trying out stored procedures for the first time, and I can't figure out what I'm doing wrong.
Here's the table definition:
CREATE TABLE `answers` (
`anid` int(11) unsigned NOT NULL auto_increment,
`uid` int(11) NOT NULL,
`dtid` int(11) NOT NULL,
`answer` text NOT NULL,
PRIMARY KEY (`anid`),
KEY `uid` (`uid`),
KEY `dtid` (`dtid`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
anid is the primary key, uid is user id, dtid is datum id, and answer is the answer provided.
Whenever I get a new answer for a given datum (question) and user id, I want to first delete any old answer to that same question by that same user, and then insert the new one.
Here's the procedure declaration:
DELIMITER //
CREATE PROCEDURE new_answer(uid INT(11),dtid INT(11),answer TEXT)
BEGIN
DELETE FROM `answers` WHERE `uid` = uid AND `dtid` = dtid;
INSERT INTO `answers` SET `uid` = uid, `dtid` = dtid, `answer` = answer;
END//
However, whenever I CALL new_answer ALL existing rows are deleted, and that one new answer is now the only row in the table.
Hope it's something simple, thanks for your help.
Rename your parameters:
DELIMITER //
CREATE PROCEDURE new_answer(p_uid INT(11),p_dtid INT(11),p_answer TEXT)
BEGIN
DELETE FROM `answers` WHERE `uid` = p_uid AND `dtid` = p_dtid;
INSERT INTO `answers` SET `uid` = p_uid, `dtid` = p_dtid, `answer` = p_answer;
END//
You should probably try naming procedure arguments different than table columns.
Anyway, it looks like all you need is a single INSERT ... ON DUPLICATE KEY UPDATE query.
I'm not familiar with stored procedures, but what about renaming your function parameters to x and y instead of the very same as the column names?