Sorry for long POST:
Is it possible that I can call a Stored Procedures from another
Stored procedure in MySQL.
For example:
I have two tables (test and testcomp):
With the structures below:
-- Table structure for table test
CREATE TABLE IF NOT EXISTS `test` (
`t_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`t_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
and
-- Table structure for table testcomp
CREATE TABLE IF NOT EXISTS `testcomp` (
`c_id` int(11) NOT NULL AUTO_INCREMENT,
`t_id` int(4) NOT NULL,
`place` varchar(255) NOT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
Now I populated test table with:
INSERT INTO `test` (`t_id`, `name`) VALUES
(1, 'foo'),
(2, 'bar'),
(3, 'ma');
and table testcomp with:
INSERT INTO `testcomp` (`c_id`, `t_id`, `place`) VALUES
(1, 1, 'gugs'),
(2, 2, 'nyanga'),
(3, 1, 'gugs'),
(4, 3, 'skom');
Now if I have 2 Procedures:
First QryTestComp:
SELECT t_id, place FROM TestComp
The one above works as the just querying normal table:
But the Second One QryTestPlac, which calls the above procedure:
SELECT * FROM Test INNER JOIN QryTestComp ON Test.t_id = QryTestComp.t_id
Comes with a error:
It says Error: 1146 (42S01): Table 'mydb.qrytestcomp' doesn't exist.
It not a table but a procedure.
Pointer, please.
Regards,
--Jongi
you can't join onto a stored procedure, perhaps using views might be more suitable ?
Related
I have two tables, and I want to use a value from primary table (here: person.ref) to extract some data from a json field in a secondary table (here: person_details):
create table person (
id int(8),
ref varchar(20),
primary key (id)
);
create table person_details (
id int(8),
details json,
primary key (id)
);
SELECT JSON_EXTRACT(details, CONCAT('$.', p.ref))
FROM person p
JOIN person_details d using (id);
The person_details data is like:
{
"ref1": {
...
}
}
But that does not matter, because the sql statement itself seems to be invalid:
Result:
#3143 - Invalid JSON path expression. The error is around character position 12.
Why?
Your code should work on MySQL >= 5.7. Check this dbfiddle:
https://dbfiddle.uk/esEJ9uHd
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ref` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `person_details` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`details` json,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `person` (`id`, `ref`) VALUES (1, 'ref1');
INSERT INTO `person` (`id`, `ref`) VALUES (2, 'ref1');
INSERT INTO `person_details` (`id`, `details`) VALUES (1, '{"ref1": {"name": "Barney"}}');
INSERT INTO `person_details` (`id`, `details`) VALUES (2, '{"ref1": {"name": "Willma"}}');
SELECT JSON_EXTRACT(details, CONCAT('$.', p.ref))
FROM person p
JOIN person_details d using (id);
While the answer above is correct, it did not solve my issue, but I had to add doublequotes around p.ref, so that the concatenation results in CONCAT($."p.ref"):
SELECT JSON_EXTRACT(details, CONCAT('$."', p.ref, '"'))
...
Suppose the schemas are
users(id, name)
users_attributes(user_id, attribute_name, attribute_value)
Sample data:
--
-- Database: `sample_db`
--
CREATE DATABASE IF NOT EXISTS `sample_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `sample_db`;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `name`) VALUES
(1, 'Tim'),
(2, 'Joe'),
(3, 'Bob');
-- --------------------------------------------------------
--
-- Table structure for table `users_attributes`
--
CREATE TABLE `users_attributes` (
`user_id` int(11) NOT NULL,
`attribute_name` varchar(50) NOT NULL,
`attribute_value` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users_attributes`
--
INSERT INTO `users_attributes` (`user_id`, `attribute_name`, `attribute_value`) VALUES
(1, 'height', '10'),
(1, 'over_18', 'yes'),
(2, 'height', '5'),
(3, 'height', '7');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `users_attributes`
--
ALTER TABLE `users_attributes`
ADD UNIQUE KEY `user_id` (`user_id`,`attribute_name`,`attribute_value`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
Right now I'm calling INNER JOIN on a specific attribute_name so my selection also returns that along with the user id and name. Now I want to exclude from whatever I selected, if they contain a certain other attribute. I know I can accomplish that by using a NOT IN (SELECT ...) conditional but can I do that without having to select again?
EDIT:
Attributes may or may not exist for all users. For example, I would like to fetch id, name, attribute_value where attribute_name = height but only if attribute_name over_18 does not exist or is 'no'
I have a MySQL table running on AWS RDS with structure like the following:
CREATE TABLE `my_table` (
`col1` int(11) NOT NULL,
`col2` int(11) NOT NULL DEFAULT '0',
`f_name` varchar(45) DEFAULT NULL,
`l_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`col1`,`col2`),
KEY `idx_col1` (`col1`),
KEY `idx_col2` (`col2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The query
SELECT * FROM my_table WHERE col1=111 AND col2=222;
returns 0 row.
But when I run an insert query
INSERT INTO my_table
(col1, col2, f_name, l_name)
VALUES (111, 222, 'John', 'Doe')
I got an error saying
Duplicate entry '111-222' for key 'PRIMARY'.
Why does this happen? The table doesn't contain a row with col1=111 and col2=222.
There's already a row with values col1=111, col2=111, f_name='John', and l_name='Doe'. But I don't think this would cause a duplicate entry error.
=========================== EDIT ======================================
There's a trigger that generates the duplicate error. Here's the script to reproduce the error.
# Initialize the tables
CREATE TABLE `my_table` (
`col1` int(11) NOT NULL,
`col2` int(11) NOT NULL DEFAULT '0',
`f_name` varchar(45) DEFAULT NULL,
`l_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`col1`,`col2`),
KEY `idx_col1` (`col1`),
KEY `idx_col2` (`col2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `triggered_table` (
`col1` int(11) NOT NULL,
`col2` int(11) NOT NULL DEFAULT '0',
`update_date` bigint(20) DEFAULT NULL,
PRIMARY KEY (`col1`,`col2`),
KEY `idx_col1` (`col1`),
KEY `idx_col2` (`col2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# Insert the data that cause duplicate error
INSERT INTO triggered_table (col1, col2) VALUES (111, 222);
# Create the trigger
DELIMITER $$
CREATE TRIGGER weird_trigger AFTER INSERT
ON my_table
FOR EACH ROW
BEGIN
INSERT INTO triggered_table
(col1, col2)
VALUES (NEW.col1, NEW.col2);
END$$
DELIMITER ;
# Create the duplicate error
INSERT INTO my_table
(col1, col2, f_name, l_name)
VALUES (111, 222, 'John', 'Doe');
I really don't understand why the developers created the triggered_table table. Why didn't they put update_date column to my_table?
This is so weird.
All you have to do is:
Truncate your table then run (Assuming that you have only a test data but if not, you have to do some backup first)
INSERT INTO my_table
(col1, col2, f_name, l_name)
VALUES (111, 222, 'John', 'Doe')
Now if the error still exists, this is a pretty much problem.
Your error seems like you concatinated col1 and col2 as your primary key ('111-222')
You can try
select * from yourTable where FieldPrimary = '111-222' if it is already exists
The duplicate key error does not come from the my_table table but from the triggered_table table instead. When you add a row in triggered_table for the key (111, 222) and then add a new row in the my_table table (with the same key), your trigger will also try to add a new row with the key (111, 222) in your triggered_table. However there is already such a key in use and you will get the duplicate key error.
Depending on what you want to do with the my_table and triggered_table tables, you might want to change the trigger to use REPLACE INTO instead of INSERT INTO. Or you run a check with SELECT first to see if you need to add a new row or not. After that you can run an UPDATE query to change the value of update_date. But to answer your question, the duplicate key error comes from the duplicate key in the triggered_table table.
Iam new to mysql
I have two tables,
CREATE TABLE `tab1` (
`tid1` int(2) NOT NULL auto_increment,
`payer` varchar(100) default NULL,
`receiver` varchar(100) default NULL,
`payAmt` decimal(20,2) default '0.00',
`recAmt` decimal(20,2) default '0.00',
PRIMARY KEY (`tid1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
--
-- Dumping data for table tab1
INSERT INTO `tab1` (`tid1`, `payer`, `receiver`, `payAmt`, `recAmt`) VALUES
(1, 'aaa', 'bbb', 100.00, -100.00),
(2, 'aaa', 'ccc', 200.00, -200.00),
(3, 'bbb', 'aaa', 150.00, -150.00),
(4, 'ccc', 'aaa', 175.00, -175.00);
--
-- Table structure for table tab2
CREATE TABLE `tab2` (
`tid2` int(2) NOT NULL auto_increment,
`payer` varchar(100) default NULL,
`receiver` varchar(100) default NULL,
`payAmt` decimal(20,2) default '0.00',
`recAmt` decimal(20,2) default '0.00',
PRIMARY KEY (`tid2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
--
-- Dumping data for table tab2
INSERT INTO `tab2` (`tid2`, `payer`, `receiver`, `payAmt`, `recAmt`) VALUES
(1, 'ddd', 'aaa', 223.00, -223.00),
(2, 'aaa', 'bbb', 429.00, -429.00),
(3, 'ccc', 'aaa', 102.00, -102.00);
I want the result as shown below
name payAmtTotal recAmtTotal payAmtTotal-recAmtTotal
aaa 729 650 79
bbb 150 529 -379
ccc 277 -277 554
ddd 223 0 223
Not sure why there is more then 1 table with this information, first thing that comes up is trying to turn this into 1 table.
Anyway, not sure if this is the best and cleanest way bu if the tables aren't to large and you have to option of creating temporary tables then here's one way of getting the desired results.
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS (SELECT * FROM `tab1`);
INSERT INTO temp1 SELECT * FROM `tab2`;
CREATE TEMPORARY TABLE IF NOT EXISTS temp2 AS (SELECT * FROM `temp1`);
CREATE TEMPORARY TABLE IF NOT EXISTS temp3 AS (SELECT * FROM `temp1`);
SELECT
`payer` AS `name`,
(SELECT SUM(payAmt) AS `p` FROM temp2 AS t WHERE t.payer = temp1.payer) AS `payAmtTotal` ,
(SELECT SUM(payAmt) AS `r` FROM temp3 AS t WHERE t.receiver = temp1.payer) AS `recAmtTotal`
FROM
temp1
GROUP BY `name`;
Basically you create a singe (temporary) table and fill this table with the data from the two existing tables.
Since MySQL won't let you use the same temporary table more then once in a single query you need to create a few more :-) they can be copies of the first one though.
After that the selection query on itself isn't that complicated.
So I've been having a problem and either I am forgetting something fundamental or I found a bug. I've narrowed it down to this:
My table:
CREATE TABLE `tbl` (
`id` int(11) NOT NULL,
`timestmp` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Simple. My query:
insert into tbl (id, timestmp) values (1, 1)
on duplicate key update timestmp = if(values(timestmp) > timestmp,
values(timestmp), timestmp)
Table will contain
(1, 1)
Repeat the query with
values (1, 2)
Table will contain
(1, 2)
Repeat the query with
values (1, 1)
Table will still contain
(1, 2)
Great. Just what we want. Instead with this table:
CREATE TABLE `tbl` (
`id` int(11) NOT NULL,
`timestmp` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Let's do the same queries:
insert into tbl (id, timestmp) values (1, 1)
on duplicate key update timestmp = if(values(timestmp) > timestmp,
values(timestmp), timestmp)
Table contains:
(1, 1)
Query with:
values (1, 2)
Table contains:
(1, 1)
What? Let's try
values (1, -1)
Table contains:
(1, -1)
JKLFSD!!!!! What's going on? Is this supposed to happen? Am I completely misinterpreting something? Do I need a special function for bigint comparison?