After inputting the triggers, the console seems in an odd state where normal commands are not responded to. Am I inadvertently doing that with the delimiter?
mysql> use nntp;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+---------------------+
| Tables_in_nntp |
+---------------------+
| articles |
| newsgroups |
| newsgroups_articles |
+---------------------+
3 rows in set (0.00 sec)
mysql> show triggers;
Empty set (0.00 sec)
mysql> DELIMITER $$
mysql> USE `nntp`$$
Database changed
mysql> CREATE
-> TRIGGER `nntp.newsgroups.before_insert`
-> BEFORE INSERT ON `nntp`.`newsgroups`
-> FOR EACH ROW
-> BEGIN
-> set new.hash = md5(new.newsgroup);
-> END$$
Query OK, 0 rows affected (0.18 sec)
mysql> DELIMITER $$
mysql> USE `nntp`$$
Database changed
mysql> CREATE
-> TRIGGER `nntp.newsgroups.before_update`
-> BEFORE UPDATE ON `nntp`.`newsgroups`
-> FOR EACH ROW
-> BEGIN
-> set new.hash = md5(new.newsgroup);
-> END$$
Query OK, 0 rows affected (0.19 sec)
mysql> show triggers;
-> ^CCtrl-C -- exit!
Aborted
thufir#dur:~$
You need to change the delimiter back when you're done creating a trigger or routine, otherwise you'll have to use the same delimiter (in this case $$) for all statements subsequently.
For example:
mysql> DELIMITER $$
mysql> USE `nntp`$$
Database changed
mysql> CREATE
-> TRIGGER `nntp.newsgroups.before_update`
-> BEFORE UPDATE ON `nntp`.`newsgroups`
-> FOR EACH ROW
-> BEGIN
-> set new.hash = md5(new.newsgroup);
-> END$$
Query OK, 0 rows affected (0.19 sec)
mysql> DELIMITER ;
mysql> show triggers;
Note the second use of the DELIMITER keyword.
Related
I want to be able to create some stored Procedures in different databases - so I want to be able to pass in the database name into the stored procedure creation statement.
SET #SourceDBName='dev';
DELIMITER //
CREATE PROCEDURE test ()
BEGIN
USE #SourceDBName;
SELECT * FROM agreed_relation;
END //
DELIMITER ;
How can I pass #SourceDBName into the CREATE PROCEDURE statement?
to pass in the database name into a stored procedure you must declare it in the procedure like this:
DELIMITER //
CREATE PROCEDURE test (IN idbname VARCHAR(20))
BEGIN
SELECT * FROM agreed_relation WHERE dbname = idbname;
END //
DELIMITER ;
After you create a Table like this where 'dbname' field it's the one your procedure will call:
create table agreed_relation
(
dbname varchar(30) not null
);
After insert some values you call the procedure and pass any dbname to the SELECT statament:
insert into agreed_relation(dbname) values('Oracle');
insert into agreed_relation(dbname) values('Mysql');
insert into agreed_relation(dbname) values('Mongodb');
Calling procedure and passing some value:
CALL test('Mysql');
14.1.16 CREATE PROCEDURE and CREATE FUNCTION Syntax
...
USE statements within stored routines are not permitted. When a
routine is invoked, an implicit USE db_name is performed (and undone
when the routine terminates). The causes the routine to have the given
default database while it executes. References to objects in databases
other than the routine default database should be qualified with the
appropriate database name.
...
An option to create the stored procedure in different databases is:
FIle: /path/to/file/myProcedure.sql
DROP PROCEDURE IF EXISTS `test`;
DELIMITER //
CREATE PROCEDURE `test`()
BEGIN
SELECT * FROM `agreed_relation`;
END//
DELIMITER ;
MySQL Command-Line:
mysql> USE `dev`;
Database changed
mysql> \. /path/to/file/myProcedure.sql
Query OK, 0 rows affected (0.00 sec)
mysql> USE `db1`;
Database changed
mysql> \. /path/to/file/myProcedure.sql
Query OK, 0 rows affected (0.00 sec)
mysql> USE `db2`;
Database changed
mysql> \. /path/to/file/myProcedure.sql
Query OK, 0 rows affected (0.00 sec)
mysql> USE `dev`;
Database changed
mysql> CALL `test`;
Empty set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> USE `db1`;
Database changed
mysql> CALL `test`;
Empty set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> USE `db2`;
Database changed
mysql> CALL `test`;
Empty set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
You can also create the stored procedure in a single database and pass the database name as a parameter to qualified the required objects and use 14.5 Prepared SQL Statement Syntax to execute it:
mysql> USE `dev`;
Database changed
mysql> DROP PROCEDURE IF EXISTS `test`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `test`(`db_name` VARCHAR(64))
-> BEGIN
-> SET `db_name` := TRIM('\'' FROM QUOTE(`db_name`));
-> SET #`query` := CONCAT('SELECT * FROM `', `db_name`, '`.`agreed_relation`');
-> PREPARE `stmt` FROM #`query`;
-> EXECUTE `stmt`;
-> DEALLOCATE PREPARE `stmt`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `test`('dev');
Empty set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> CALL `test`('db1');
Empty set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> CALL `test`('db2');
Empty set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
I created two tables
CREATE TABLE `prova` (
`id` int NOT NULL AUTO_INCREMENT ,
`text` varchar(255) NOT NULL ,
PRIMARY KEY (`id`)
)
;
CREATE TABLE `prova2` (
`id2` int NOT NULL AUTO_INCREMENT ,
`text2` varchar(255) NOT NULL ,
PRIMARY KEY (`id2`)
)
;
insert into prova (text) values ('ffffff');
A function does a select on table one and inserts a row in table two only if the value of variable #test is set to 0:
CREATE FUNCTION `get_prova`()
RETURNS int(11)
BEGIN
declare id_prova int ;
declare test int ;
set #test = 1;
set #id_prova = (select id from prova limit 1);
if (#test = 0) THEN
insert into prova2 (text2) values ('dddd');
end if;
return #id_prova;
END;
then, I create a view that calls this function:
create view temp_prova as
select id,
text,
get_prova() as prova
from prova
I want to create table 3 that contains the result of view:
CREATE TABLE zzz_prova SELECT * FROM temp_prova;
but when I try to create table zzz_prova I get this error:
[SQL]CREATE TABLE zzz_prova SELECT * FROM temp_prova; [Err] 1746 -
Can't update table 'prova2' while 'zzz_prova' is being created.
Why does this error show up?
Thank you
What version of MySQL are you running?
Changes in MySQL 5.6.2 (2011-04-11)
Incompatible Change; Replication: It is no longer possible to issue a
CREATE TABLE ... SELECT statement which changes any tables other than
the table being created. Any such statement is not executed and
instead fails with an error.
One consequence of this change is that FOR UPDATE may no longer be
used at all with the SELECT portion of a CREATE TABLE ... SELECT.
This means that, prior to upgrading from a previous release, you
should rewrite any CREATE TABLE ... SELECT statements that cause
changes in other tables so that the statements no longer do so.
This change also has implications for statement-based replication
between a MySQL 5.6 (or later slave) and a master running a previous
version of MySQL. In such a case, if a CREATE TABLE ... SELECT
statement on the master that causes changes in other tables succeeds
on the master, the statement nonetheless fails on the slave, causing
replication to stop. To keep this from happening, you should either
use row-based replication, or rewrite the offending statement before
running it on the master. (Bug #11749792, Bug #11745361, Bug #39804,
Bug #55876)
References: See also Bug #47899.
UPDATE
MySQL 5.5:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.5.47 |
+-----------+
1 row in set (0.00 sec)
mysql> DROP FUNCTION IF EXISTS `f`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `t1`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `t2`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER |
mysql> CREATE FUNCTION `f`()
-> RETURNS INT
-> BEGIN
-> INSERT INTO `t2` VALUES (1);
-> RETURN 1;
-> END|
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CREATE TABLE `t2`(`c1` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `t1` SELECT `f`() `c1`;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT `c1` FROM `t1`;
+------+
| c1 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> SELECT `c1` FROM `t2`;
+------+
| c1 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
MySQL 5.6:
mysql> SELECT VERSION();
+-----------------+
| VERSION() |
+-----------------+
| 5.6.25 |
+-----------------+
1 row in set (0.00 sec)
mysql> DROP FUNCTION IF EXISTS `f`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP TABLE IF EXISTS `t1`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP TABLE IF EXISTS `t2`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DELIMITER |
mysql> CREATE FUNCTION `f`()
-> RETURNS INT
-> BEGIN
-> INSERT INTO `t2` VALUES (1);
-> RETURN 1;
-> END|
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CREATE TABLE `t2`(`c1` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `t1` SELECT `f`() `c1`;
ERROR 1746 (HY000): Can't update table 't2' while 't1' is being created.
I am trying to create event for one of my database using below code,
use testing;
show events;
show warnings;
set global event_scheduler =on;
DELIMITER $$
create event table_backup_testingTo_test on schedule every 1 day
starts '2015-10-14 16:40:00'
do
select * into test.event_table_testing from testing.manitest;
DELIMITER $$
After run this code if i check in show events then there is no event in the name of table_backup_testingTo_test
where am i doing mistake?
Note : I am using mysql workbench 6.3
You change the delimiter, but actually never finish a statement with it. And after the multiple statements you should change the delimiter back to default. In your case you don't need a delimiter at all, since it's just one statement. Try like this:
DELIMITER ; /*assuming it's still set to $$*/
use testing;
show events;
show warnings;
set global event_scheduler =on;
create event table_backup_testingTo_test on schedule every 1 day
starts '2015-10-14 16:40:00'
do
select * into test.event_table_testing from testing.manitest;
Or, if you have multiple statements in your event:
use testing;
show events;
show warnings;
set global event_scheduler =on;
DELIMITER $$
create event table_backup_testingTo_test on schedule every 1 day
starts '2015-10-14 16:40:00'
do
begin
select * into test.event_table_testing from testing.manitest;
select 'we have multiple statements here';
end $$
DELIMITER ;
My test:
mysql> CREATE DATABASE `testing`;
Query OK, 1 row affected (0.00 sec)
mysql> USE `testing`;
Database changed
mysql> CREATE TABLE `manitest` (
-> `column_0` int,
-> `column_1` varchar(7),
-> `column_2` varchar(55)
-> );
mysql> INSERT INTO `manitest`
-> (`column_0`, `column_1`, `column_2`)
-> VALUES
-> (1, 'value_1_0', 'value_2_0'),
-> (2, 'value_1_1', 'value_2_1'),
-> (3, 'value_1_2', 'value_2_2');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> CREATE DATABASE `test`;
Query OK, 1 row affected (0.00 sec)
mysql> USE `test`;
Database changed
mysql> CREATE TABLE `event_table_testing` (
-> `column_0` int,
-> `column_1` varchar(7),
-> `column_2` varchar(55)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * INTO `test`.`event_table_testing`
-> FROM `testing`.`manitest`;
ERROR 1327 (42000): Undeclared variable: test
mysql> INSERT INTO `test`.`event_table_testing`
-> SELECT * FROM `testing`.`manitest`;
Query OK, 3 rows affected (0.00 sec)
mysql> CREATE EVENT `table_backup_testingTo_test` ON SCHEDULE EVERY 1 DAY
-> STARTS '2015-10-14 16:40:00'
-> DO
-> -- select * into test.event_table_testing from testing.manitest;
-> INSERT INTO `test`.`event_table_testing`
-> SELECT * FROM `testing`.`manitest`;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW EVENTS\G
*************************** 1. row ***************************
Db: test
Name: table_backup_testingTo_test
.
.
.
1 row in set (0.00 sec)
I've inherited some code that uses stored procedures and one of them doesn't appear to be working correctly.
The stored procedure uses a temporary table to insert data later in the procedure. However when I execute the stored procedure, no data is inserted. When I debug it, I get the error:
Table 'db.testtable' doesn't exist
I've stripped down the stored procedure to the following code, and it doesn't work. I always get the error on the SELECT statement. Everything looks OK from what I can tell based on the examples I've seen.
DROP PROCEDURE IF EXISTS db.insert_record;
CREATE PROCEDURE db.`insert_record`(id int, status int)
BEGIN
DECLARE code varchar(45);
DROP TEMPORARY TABLE IF EXISTS testTable;
CREATE TEMPORARY TABLE testTable AS (SELECT 'TEST' AS fakeColumn);
SELECT fakeColumn INTO code FROM testTable;
END;
I've also verified that the user I am connected as has the permission to create temporary tables; in fact it has every permission available
Additional Details
Running MySQL 5.6 on Windows.
If I take the drop / create / select statements by themselves and run as a script, it behaves as expected.
Using Toad for MySQL to debug the stored procedure.
I can't reproduce the problem. What other information can you provide?
mysql> USE `test`;
Database changed
mysql> SELECT VERSION();
+-----------------+
| VERSION() |
+-----------------+
| 5.5.22-0ubuntu1 |
+-----------------+
1 row in set (0.00 sec)
mysql> DELIMITER //
mysql> DROP PROCEDURE IF EXISTS `insert_record`//
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE PROCEDURE `insert_record`(`id` int, `status` int)
-> BEGIN
-> DECLARE `code` VARCHAR(45);
-> DROP TEMPORARY TABLE IF EXISTS `testTable`;
-> CREATE TEMPORARY TABLE `testTable` AS (SELECT 'TEST' AS `fakeColumn`);
-> SELECT `fakeColumn` INTO `code` FROM `testTable`;
-> SELECT `code`;
-> END//
Query OK, 0 rows affected (0.01 sec)
mysql> CALL `insert_record`(NULL, NULL)//
+--------+
| `code` |
+--------+
| TEST |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
SQL Fiddle demo
I am creating procedure in mysql. but I am facing some issues while creating that.
I am applying query i.e
CREATE PROCEDURE simpleproc( param1 INT) BEGIN SELECT COUNT(*)
INTO param1 FROM 91_nidhi; END//
and The error is
#1064 - You have an error in your SQL syntax; c
heck the manual that corresponds to your MySQL server version for the
right syntax to use near '' at line 1
This how you need to do
- You are not passing any input value rather you are using an output value
- so specify the param as OUT
Below is the example
mysql> create table 91_nidhi (id int,val varchar(20));
Query OK, 0 rows affected (0.09 sec)
mysql> insert into 91_nidhi values (1,'aa'),(2,'bb'),(3,'cc');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
Now lets create the procedure
delimiter //
CREATE PROCEDURE simpleproc( out param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM 91_nidhi;
END; //
Then change the delimiter in the terminal as
mysql> delimiter ;
Now lets call the procedure
mysql> call simpleproc(#res);
Query OK, 0 rows affected (0.00 sec)
mysql> select #res ;
+------+
| #res |
+------+
| 3 |
+------+
1 row in set (0.00 sec)