MySQL: Use a select statement for stored procedure parameter - mysql

I have a stored procedure that works:
call my_procedure('A,B,C,D');
I want to populate the A,B,C with a list from a subquery of another table, eg:
call my_procedure(
SELECT group_concat(letters) FROM table WHERE type = 'some_type')
);
Possible? Or am I doing it wrong?

SELECT my_function(group_concat(letters)) FROM table WHERE type = 'some_type';

You can assign the value to a user-defined variable and then pass that variable to the function.
For example:
SELECT group_concat(letters)
INTO #foo
FROM table
WHERE type = 'some_type';
call my_function(#foo);

Yes, you can pass a string to a procedure that's returned as the result of subquery.
But not as a bare query:
mysql> create procedure foo (in s text) begin select s; end !!
mysql> call foo( select group_concat(user) from mysql.user );
ERROR 1064 (42000): 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
'select group_concat(user) from mysql.user )' at line 1
If you enclose the query in parentheses, it counts as a scalar subquery, that is, a subquery that is bound to return one row, one column:
mysql> call foo( (select group_concat(user) from mysql.user) );
+--------------------+
| s |
+--------------------+
| root,root,bill,xbm |
+--------------------+

Related

Check if a row exists using MySQL 8 version

I have this query in MySQL database 8.0.12 version
mysql> SELECT tTbl INTO #tTbl FROM t_table WHERE tTbl = "t_contents_1_2021";
SELECT #tTbl;
Query OK, 1 row affected (0.07 sec)
+-------------------+
| #tTbl |
+-------------------+
| t_contents_1_2021 |
+-------------------+
1 row in set (0.07 sec)
Now I need test whether a row exists in a MySQL table or not, using exists condition.
The exists condition can be used with subquery.
It returns true when row exists in the table, otherwise false is returned. True is represented in the form of 1 and false is represented as 0.
I have tried without success
mysql> SELECT EXISTS(SELECT tTbl INTO #tTbl FROM t_table
WHERE tTbl = "t_contents_1_2021");
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 '(SELECT tTbl INTO #tTbl FROM t_table
WHERE tTbl' at line 1
mysql>
How to do resolve this?
SELECT .. INTO does not return the rowset. EXISTS needs in rowset. So SELECT .. INTO cannot be used in EXISTS.
Remove it:
SELECT EXISTS ( SELECT tTbl
FROM t_table
WHERE tTbl = "t_contents_1_2021" );
If you need both check the row existence and save the value to the variable then use inline assigning:
SELECT EXISTS ( SELECT NULL
FROM t_table
WHERE (#tTbl := tTbl) = "t_contents_1_2021" );

MySQL Trigger to Auto generating a number if not supplied

Is it possible to auto generate a number if nothing is supplied for a column in the table
#SurveyId,Name,PhoneNumber
1,David,071234234
1,John, NULL
expected output
#SurveyId,Name,PhoneNumber
1,David,071234234
1,John, 3274985AUTO
I would like to write a trigger for my table to carry out the auto generation option; i would like to use UUID() for auto generating number
syntax error:
15:10:23 CREATE TRIGGER mobilecheck BEFORE INSERT ON reg02_maininfo `FOR EACH ROW IF NEW.farmermobile IS NULL THEN SET NEW.farmermobile = floor(rand()*900000)+100000 Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 2 0.0015 sec`
You could do it this way
SELECT SurveyId, Name, IFNULL(PhoneNumber,floor(rand()*900000)+100000) as PhoneNumber FROM table
I did not add an AUTO at the end as if the field only accepts an integer it will give you an error.
You could also update your table to directly replace all null values
UPDATE Table SET PhoneNumber = floor(rand()*900000)+100000
WHERE PhoneNumber IS NULL;
For a trigger you could use the following :
CREATE TRIGGER phonecheck BEFORE INSERT ON tablename FOR EACH ROW IF NEW.PhoneNumber IS NULL THEN SET NEW.PhoneNumber = floor(rand()*900000)+100000; END IF;
COALESCE to fetch it if it's non-null, FLOOR+RAND to get a random number otherwise, CONCAT to add AUTO at the end?
SELECT `#SurveyId`,`Name`,COALESCE(`PhoneNumber`,CONCAT((FLOOR(RAND()*(9999999-1000000+1))+1000000),'AUTO')) AS PhoneNumber

How to call a stored procedure using select statement in mysql

I have call statement like
CALL report_procedure
('2013-02-01',now(),'2015-01-01','1');
and i want to use it in a select query.
i have tried like
Select * from ( CALL report_procedure
('2013-02-01',now(),'2015-01-01','1'));
but error occurs.
like
Error Code: 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 ( CALL report_procedure
('2013-02-01',now(),'2015-01-01','1') at line 3 0.297 sec
Can anyone suggest me a method to call stored procedure in Select statement in mysql??
It is not possible to use result set from procedure in FROM clause. MySQL does not allow doing this.
You may populate another table (or temporary table) in your procedure, and after, use that table in SELECT commands -
CALL report_procedure ('2013-02-01',now(),'2015-01-01','1'); -- fill temp_table
SELECT * FROM temp_table;
--Firstly your store procedure should look something like this:
CREATE PROCEDURE report_procedure(
IN d1 DATE,
dnow DATE,
d2 DATE,
val INT
)
BEGIN SELECT *
FROM yourtablename
WHERE date1 = d1
AND datenow > dnow
AND date2 > d2
AND value = val;
END
--The store procedure contains the select statement.
-- then you can call the store procedure like that:
CALL report_procedure('2013-02-01',now(),'2015-01-01','1');
--hope it helps

MySQL if statement fails

I have a function called tableExists. It can be used to check for the existence of a table. I want to use it in a DB upgrade script. I can use the function like this:
select myDb.tableExists('myDb', 'someTable') as cnt into #exists;
And see the results like this:
mysql> select #exists;
+---------+
| #exists |
+---------+
| 1 |
+---------+
Now, I want to use it in an If statement, followed by a create table statement. But, I am having problems with the if. The following is what I am trying to test with:
mysql> IF (#exists = 1) THEN
-> select 'exists'
-> END IF;
ERROR 1064 (42000): 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 'IF (#exists = 1) THEN
select 'exists'
END IF' at line 1
What am I missing here? This should be simple.
You can only use the IF inside a stored procedure.
The valid select statement would be:
SELECT CASE (#exists) WHEN 1 THEN 'exists' END as DoesItExist
If you use the case as a stand alone element in a stored proc, you'll need to end it with end case how ever.
Why don't you just use IF NOT EXISTS in the CREATE TABLE query and save yourself all this trouble:
CREATE TABLE new_table IF NOT EXISTS
... {table definition}
If the table already exists, nothing will happen.

Using a MySQL event to "deactivate" accounts

I setup a database and one of the columns in a table is "status" (active,inactive,locked). I want the event to compare NOW() to the value of column "pdate" (which is a timestamp), and if greater than 30 days, update the value of "status" to "inactive".
I wrote the following, but I get a few syntax errors :s
CREATE EVENT `expireAccounts_oldPwd` ON SCHEDULE EVERY DAY
DO
USE databasename;
SELECT pdate FROM tablename WHERE status = "active";
FOR EACH ( ROW IN tablename WHERE( ( SELECT DATEDIFF(NOW(),pdate) AS age ) > 30 ) ) {
UPDATE tablename SET status = "inactive";
};
ERROR 1064 (42000): You have an error in your SQL syntax near 'USE databasename' at line 2
ERROR 1064 (42000): You have an error in your SQL syntax near 'FOR EACH ROW IN "tablename" WHERE( ( SELECT DATEDIFF(NOW(),"pdate") AS age )' at line 4
ERROR 1064 (42000): You have an error in your SQL syntax near '}' at line 6
of course 'databasename' was replaced the actual database's name and 'tablename' the actual table's name.
Now at least it's doing something:
+---------------------+
| pdate |
+---------------------+
| 2011-08-11 18:01:02 |
| 2011-08-11 18:03:31 |
+---------------------+
2 rows in set (0.00 sec)
If I don't included USE databasename; on line 2, I get no output.
FINAL CODE:
USE databasename;
DELIMITER %
CREATE EVENT eventname
ON SCHEDULE EVERY 1 DAY
DO UPDATE tablename SET status = "inactive" WHERE status = "inactive" AND DATEDIFF(NOW(), columnname) > 30);
%
I didn't realize events were database-specific (so you have to be in the database when you create it).
Thanks all!
Two event specific things apart from the obvious syntax problems:
Where does your event end? You need to enclose it in a BEGIN/END block (the same way as a stored procedure).
You need to switch the DELIMITER when defining an event (the same way as when you define a stored procedure).
There are two relevant examples at the end of http://dev.mysql.com/doc/refman/5.1/en/create-event.html.
Update:
Also check http://dev.mysql.com/doc/refman/5.1/en/stored-routines-syntax.html for SQL statements which are permitted in stored procedures and events. USE is not permitted.
One more update:
It would be advisable to first try to get your SQL working without putting it in a event. After you have fixed your statements so that they work, try creating a stored procedure out of it. When you get the stored procedure working, you can replace it with an event. This way it will be much easier to sort out the rest of the problems (such as where is the output of the first SELECT supposed to go? etc.).
Is there a reason you can't use a query like this one?
UPDATE tablename SET status = "inactive" WHERE status = "active" AND DATEDIFF(NOW(),pdate) > 30;
I've never even seen FOR EACH in MySQL...
First step's going to be using valid SQL.
SELECT "pdate" FROM databasename.tablename WHERE "status" = "active";
will always cause an error, because column names shouldn't be in quotes. If you enclose a table name in anything, it'd be backticks (`).
SELECT pdate FROM databasename.tablename WHERE status="active";
You have the same problem in the rest of your query.