So i have a problem. I do not know how to write a trigger that not only sends datafrom (Table1) to another table(Table2), but edits it as well as seen in image link - Full transformation at end of the question
use ptype;
create table IDVU (
`ID` int(8) unsigned not null auto_increment ,
`VU` varchar(45) not null,
PRIMARY KEY (`id`),
KEY `ix_VU` (`VU`)
)ENGINE = InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
create table sep (
ID1 int(8) unsigned NOT NULL primary key auto_increment,
ID2 int(8) unsigned not null,
V varchar(45) not null,
U varchar(45) not null,
KEY `ix_ID2` (`ID2`),
CONSTRAINT `ID_IDVU_SEP` FOREIGN KEY (`ID2`) REFERENCES `IDVU` (`ID`) ON
DELETE CASCADE ON UPDATE CASCADE
)ENGINE = InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
delimiter $$
CREATE TRIGGER `edit` AFTER INSERT
ON `idvu`
FOR EACH ROW BEGIN
IF new.VU like '% %' THEN
SET #V = SUBSTRING_INDEX(SUBSTRING_INDEX(new.Vu, ' ', 1), ' ', -1) ,
#U = SUBSTRING_INDEX(SUBSTRING_INDEX(new.Vu, ' ', 2), ' ', -1);
else
SET #V = 'NEW',#U = 'NEW';
END IF;
INSERT INTO sep (ID2,V, U) VALUES (new.ID,#V, #U);
END$$
delimiter ;
LOAD DATA LOCAL INFILE '/Users/MarcisL/Desktop/MySQL faili/CSV/PTCSV.csv' ignore
INTO TABLE IDVU FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
This is a code that I want to use as base ,because trigger worked very similary in my opinion to what i want now. Code work like this - if table2(IDVU) was updated than table3(sep) was updated and Player(VU) column from table2(IDVU) was split into Name(V),Surname(U) -Full transformation at end of the question
In the end my whole script should work like this - Full transformation
Another my question on this site turned into answer for this question!
Trigger does not recognize table (Trigger to break up content of NEW.values into multiple rows to insert into another table)
Related
I have a scenario where i have one main table. Main table has 2 extra columns one is for table name (child table name) and other is for table id (child table id). when we enter the value in main table we also tell enter value in child table and then we enter the name of the table in main table name field and child id in the child field of the main table.
now when i query i need to join query with child table in a way that i picks up the table name from the column and join query with that table with concat function and then join on child id.
below is the structure of the table and also there values
CREATE TABLE IF NOT EXISTS `tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tbl_type` enum('multi','gift','pledge') DEFAULT NULL,
`tbl_type_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
INSERT INTO `tbl` (`id`, `timestamp`, `tbl_type`, `tbl_type_id`) VALUES
(1, '2015-03-09 09:39:42', '', 1),
(2, '2015-03-09 22:43:23', 'multi', 2),
(3, '2015-03-09 23:26:38', 'gift', 1),
(4, '2015-03-10 09:46:15', 'pledge', 2);
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `tbl_gift` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`amount` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `tbl_gift` (`id`, `amount`) VALUES
(1, '1231200'),
(2, '1231200');
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `tbl_multi` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`amount` float(255,0) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `tbl_pledge` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`amount` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `tbl_pledge` (`id`, `amount`) VALUES
(1, '10000'),
(2, '10200');
so this is simple hard code query
select * from tbl t left join tbl_gift g on g.id = t.tbl_type_id
but i want to make it dynamic i tried this
select * from tbl t left join (concat('tbl', '_', t.tbl_type)) g on g.id = t.tbl_type_id
should get the table which i need
(concat('tbl', '_', t.tbl_type))
but it get 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 '('tbl', '_', t.tbl_type)) g on g.id = t.tbl_type_id LIMIT 0, 30' at line 1
The comments by Ankit and Usedby answered your question.
SQL does not allow you to provide dynamically constructed table names as you attempted. They provided you with two options: 1) Construct your query dynamically on the PHP side, then SQL see only the static table names or
2) Use the SQL PREPARE command to construct the dynamic table name and the EXECUTE SQL command to execute it.
I have 2 tables:
Warehouse (Parent)
Subwarehouse (Child)
Here is the creation of tables
//Create Warehouse Table
function einv_createWarehouseTable($conn, $db_type){
// Create SQL Statement To Create Table according to Database
$sql = "
CREATE TABLE IF NOT EXISTS `einv_warehouse` (
`einv_wh_id` INT(11) NOT NULL AUTO_INCREMENT,
`einv_wh_code` VARCHAR(4) NOT NULL,
`einv_wh_name` VARCHAR(255) NOT NULL,
`einv_wh_desc` TEXT NOT NULL,
`einv_wh_remark` TEXT NULL,
PRIMARY KEY (`einv_wh_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
";
//Create Sub Warehouse Table
function einv_createSubWarehouseTable($conn, $db_type){
// Create SQL Statement To Create Table according to Database
$sql = "
CREATE TABLE IF NOT EXISTS `einv_subwarehouse` (
`einv_whs_id` INT(11) NOT NULL AUTO_INCREMENT,
`einv_whs_wh_id` INT(11) NOT NULL,
`einv_whs_code` VARCHAR(4) NOT NULL,
`einv_whs_name` VARCHAR(255) NOT NULL,
`einv_whs_desc` TEXT NOT NULL,
`einv_whs_remark` TEXT NULL,
PRIMARY KEY (`einv_whs_id`),
FOREIGN KEY (`einv_whs_wh_id`) REFERENCES einv_warehouse(`einv_wh_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
";
I would like to be able to delete my parent table alongside clearing the entire child data.
I'd prefer an alternative method besides using on delete cascade which will result me into altering the table.
It is troublesome because these codings would require a drop and install process which is time consuming since there are many existing tables.
tl;dr - another method to delete all child data when selected parent id is
deleted
besides using on delete cascade
Here is my delete sql in my function.php page:
base_executeSQL("DELETE FROM einv_warehouse WHERE einv_wh_id = " . $whid . "");
base_executeSQL("DELETE FROM einv_subwarehouse WHERE einv_whs_id = " . $whid . "");
I am trying to duplicate a page in the database and all related rows.
The problem I am having is because the page_group_id is an identifier for both tables. Is there any way of doing this without looping each of the new "page_groups" records?
pages (page_id, page_name, etc)
page_groups (page_group_id, page_id, etc)
page_group_items (page_group_id, item_id, etc)
UPDATE:
--
-- Table structure for table `pages`
--
CREATE TABLE IF NOT EXISTS `pages` (
`page_id` int(11) NOT NULL AUTO_INCREMENT,
`page_name` varchar(255) NOT NULL,
PRIMARY KEY (`page_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `pages`
--
INSERT INTO `pages` (`page_id`, `page_name`) VALUES
(1, 'My Page'),
(2, 'My other page');
-- --------------------------------------------------------
--
-- Table structure for table `page_groups`
--
CREATE TABLE IF NOT EXISTS `page_groups` (
`page_group_id` int(11) NOT NULL AUTO_INCREMENT,
`page_group_name` varchar(255) NOT NULL,
`page_id` int(11) NOT NULL,
PRIMARY KEY (`page_group_id`),
KEY `page_id` (`page_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `page_groups`
--
INSERT INTO `page_groups` (`page_group_id`, `page_group_name`, `page_id`) VALUES
(1, 'My Group', 1),
(2, 'My Group', 2);
-- --------------------------------------------------------
--
-- Table structure for table `page_group_items`
--
CREATE TABLE IF NOT EXISTS `page_group_items` (
`page_group_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
KEY `item_id` (`item_id`),
KEY `page_group_id` (`page_group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `page_group_items`
--
INSERT INTO `page_group_items` (`page_group_id`, `item_id`) VALUES
(1, 1),
(1, 2),
(1, 3),
(2, 1),
(2, 2);
Since you're replacing the only unique identifier in each table (the primary key) when copying, I can't see a way of doing it without adding temporary anchor columns to the tables, do the copy and remove them again. Something like this;
ALTER TABLE pages ADD originalpageid INT;
UPDATE pages set originalpageid=page_id;
ALTER TABLE page_groups ADD originalpagegroupid INT;
UPDATE page_groups SET originalpagegroupid=page_group_id;
INSERT INTO pages (page_name,originalpageid)
SELECT page_name,originalpageid FROM pages;
INSERT INTO page_groups (page_group_name,page_id,originalpagegroupid)
SELECT page_group_name,MAX(pages.page_id),originalpagegroupid
FROM page_groups
JOIN pages
ON page_groups.page_id=originalpageid
GROUP BY originalpageid,page_group_name,originalpagegroupid;
INSERT INTO page_group_items(page_group_id,item_id)
SELECT MAX(page_groups.page_group_id),item_id
FROM page_group_items
JOIN page_groups
ON page_group_items.page_group_id=originalpagegroupid
GROUP BY originalpagegroupid,item_id;
ALTER TABLE pages DROP COLUMN originalpageid;
ALTER TABLE page_groups DROP COLUMN originalpagegroupid;
An SQLfiddle to test with
If the use case is doing it all the time in the system, it may not be the solution you're looking for, but for manual intervention it should work well.
As always, always back your database up before running SQL from random strangers on the Internet :)
Let assume we've database table My_table with (id-name)
CREATE TABLE `drink` (
`id` int(5) NOT NULL auto_increment,
`name` varchar(64) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=9034 ;
INSERT INTO `My_table` VALUES (1, 'my name is someone');
How to automate adding new fields using php or something else so that it can be (id-new-name)
and where new = name after we replace spaces to - using
$new = str_replace(' ', '-', trim($name));
so the table become
CREATE TABLE `drink` (
`id` int(5) NOT NULL auto_increment,
`new` varchar(64) NOT NULL default '',
`name` varchar(64) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=9034 ;
INSERT INTO `My_table` VALUES (1, 'my-name-is-someone', 'my name is someone');
I'd like to operate it cause it has half million of lines and impossible to do it manually
so any idea!
Thanks for help.
You might want to do that:
Adding a new column to the table:
ALTER TABLE drink ADD new varchar(100) after id;
Setting values for the new column using the pattern you described:
UPDATE drink SET new = REPLACE(name, ' ', '-');
RESOURCES:
http://dev.mysql.com/doc/refman/5.5/en/alter-table.html
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
When you insert anything i MySQL you have to specify the columns..Like this
INSERT INTObanans(id,sort) VALUES ('1','Green')
If you only need the value back, and don't need to search by new, you can:
SELECT id, REPLACE(name, ' ','-') AS new, name
FROM drink
Similar to what Macovei suggested, you can generate the new name when you insert a new record by doing this:
INSERT INTO drink (new, name) VALUES ('the name', REPLACE('the name', ' ', '-'))
I have an MySQL table named i_visited structured like: userid,tid,dateline
And I run this condition in view_thread.php page:
if (db('count','SELECT userid FROM i_visited
WHERE tid = '.intval($_GET['id']).'
AND userid = '.$user['id']))
mysql_query('UPDATE i_visited
SET dateline = unix_timestamp(now())
WHERE userid = '.$user['id'].'
AND tid = '.intval($_GET['id']));
else
mysql_query('INSERT INTO i_visited (userid,tid,dateline) VALUES
('.$user['id'].','.intval($_GET['id']).',unix_timestamp(now()))');
The problem is that it executes in 80/100 ms (on Windows) 40/60 (on Linux)
1 row affected. (query executed in 0.0707 sec)
The mysql_num_rows() aka db('count',sql) uses 2 / 3 ms, so the problem is at the update and the insert.
P.S. i_visited is an utf8_unicode_ci (InnoDB), has anyone seen this problem?
Other queries run normal (2 / 3 milliseconds)
CREATE TABLE i_visited (
userid int(10) NOT NULL,
tid int(10) unsigned NOT NULL,
dateline int(10) NOT NULL,
KEY userid (userid,tid),
KEY userid_2 (userid),
KEY tid (tid) )
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
You do not need to do a select to check existence and then choose either Update or Insert.
You can use MySQL's ON DUPLICATE KEY UPDATE Feature like this.
$query = 'INSERT INTO
i_visited (userid,tid,dateline)
VALUES (' .
$user['id'] . ',' .
intval($_GET['id']) . ',
unix_timestamp(now()))
ON DUPLICATE KEY UPDATE
dateline = unix_timestamp(now())';
mysql_query($query);
This query will insert a new row if there is now KEY conflict, and in case a duplicate key is being inserted, it will instead execute the update part.
And as you have a KEY userid (userid,tid) in your CREATE Statement the above query is equivalent to your if...else block.
Try this and see if there are any gains
You can also use REPLACE INTO, as there are only the specified 3 columns, like this
$query = 'REPLACE INTO
i_visited (userid,tid,dateline)
VALUES (' .
$user['id'] . ',' .
intval($_GET['id']) . ',
unix_timestamp(now()))';
mysql_query($query);
But I would suggest looking at ON DUPLICATE KEY UPDATE as it is more flexible, as it can be used on a table with any number of columns, whereas REPLACE INTO would only work in some limited cases as other column values would also need to be filled in the REPLACE INTO statement unnecessarily
I think (part) of the problem is that your table does not have an explicit primary key.
You've only declared secondary keys.
Change the definition to:
CREATE TABLE i_visited (
userid int(10) NOT NULL,
tid int(10) unsigned NOT NULL,
dateline int(10) NOT NULL,
PRIMARY KEY userid (userid,tid), <<----------
KEY userid_2 (userid),
KEY tid (tid) )
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
InnoDB does not work well without an explicit primary key defined.