comparing between date in mysql - mysql

i have a stored procedure in mysql that doesnt work i need to compare a column that his name i get as parameter and a date that his value i allso get as parameter' my syntax is this.
DELIMITER $$
CREATE DEFINER=`vladiraheli`#`%` PROCEDURE sheepfarm.create_date_filter
(
in columnName VARCHAR(100),
in param varchar(100),
in val varchar(100)
)
BEGIN
declare formated_date date;
set formated_date = str_to_date(val,'%Y-%m-%d');
set #stmt1 = concat(
'select * from sheepfarm.Sheep where ' +
columnName + param + 'formated_date') ;
prepare stmt1 from #stmt1;
EXECUTE stmt1;
END $$
how can i make this work??
thank you vaery much for your help

it has a problem with this statement:
set #stmt1 = concat('select * from sheepfarm.Sheep where ' +
columnName + param + 'formated_date') ;
formated_date is passed as string, not as a variable.
set #stmt1 = concat('select * from sheepfarm.Sheep where ',
columnName, ' ', param, ' ', formated_date) ;
Since you are using CONCAT, you should use comma instead of plus sign.
Question, what are the possible values of columnName, param and val?

Related

First Stored procedure with parameter in MySQL

this is my query in MySQL on table tbl_T367
mysql> SELECT
oID,
xName
FROM
`tbl_T367`
WHERE
oID IN ('2')
AND xName IN ('T367');
+-----+-------+
| oID | xName |
+-----+-------+
| 2 | T367 |
+-----+-------+
1 row in set
i need create mysql stored procedure for the same output like above
my code below
DELIMITER $$
DROP PROCEDURE IF EXISTS my_sqrt$$
CREATE PROCEDURE my_sqrt(xName char(4), oID INT (11))
BEGIN
DECLARE xNamenew CHAR (4);
DECLARE IDnew INT (11);
SET #xNamenew = xName;
SET #IDnew = oID;
SET #s = CONCAT('SELECT * FROM tbl_', #xNamenew,
' WHERE oID IN (' + #IDnew + ') AND xName IN (' + #xNamenew + ')');
PREPARE stmt FROM #s;
EXECUTE stmt;
END
DELIMITER ;
but the result
Procedure execution failed
1146 - Table 'tbl_T3672' doesn't exist
why was the value of the second variable added to the table name?
mysql> SELECT
oID,
xName
FROM
`tbl_T3672`
WHERE
oID IN ('2')
AND xName IN ('T367');
1146 - Table 'tbl_t3672' doesn't exist
mysql>
how to do resolve this?
update
SET #s = CONCAT('SELECT * FROM tbl_', #xNamenew,
' WHERE oID IN (' , #IDnew , ') AND xName IN (' , #xNamenew ,')');
PREPARE stmt FROM #s;
EXECUTE stmt;
Procedure execution failed
1054 - Unknown column 'T367' in 'where clause'
Some issues (I haven't reviewed the original procedure thoroughly):
MySQL doesn't have a string concatenation operator. + is the addition operator thus your strings will be cast to numbers and added.
You're inflicting yourself SQL injection. Literal strings in SQL must be single-quoted, but that isn't something you need to take care yourself.
You're invoking the procedure from itself.
You are missing the ending delimiter.
DROP PROCEDURE IF EXISTS my_sqrt;
DELIMITER $$
CREATE PROCEDURE my_sqrt(xName char(4), oID INT (11))
BEGIN
DECLARE xNamenew CHAR (4);
DECLARE IDnew INT (11);
SET #xNamenew = xName;
SET #IDnew = oID;
SET #s = CONCAT('SELECT * FROM tbl_', #xNamenew,
' WHERE oID = ? AND xName = ?');
PREPARE stmt FROM #s;
EXECUTE stmt USING #IDnew, #xNamenew;
END
$$
DELIMITER ;
CALL my_sqrt('T367', '2');
Alvaro's answer shows you how to use parameterized queries to reduce the chances of injection. This procedure below is just for educational purposes to show you the difference between what you had and how close you were to getting it right.
There are some variables you didn't need. You can take the input and create a concatenated string. Since you would send '2', it may not be concatenated with the single quotes. So, you have to include single quotes in the concatenation like shown below.
delimiter $$
drop procedure if exists my_sqrt$$
create procedure my_sqrt(xName varchar(10), oID varchar(10))
begin
set #s = concat(
"select * from tbl_", xName,
" where oID in ('", oID, "')",
" and xName in ('", xName, "')"
);
prepare stmt from #s;
execute stmt;
end$$
delimiter ;
Again, this is for educational purposes. Use Alvaro's method.

SQL - Get databases which contain a specific record

So originally I have this as a test run.
SELECT DISTINCT table_schema FROM information_schema.columns WHERE table_schema LIKE '%or';
I have looked around and found queries to show all the databases that contain a specific table.
However is it possible to have a query to go a step further and do the following:
"Select all those databases that have a particular table in them and that, in that table, have a particular record in a particular column."?
You cannot do what you want with a SQL statement.
But, you can use SQL to generate the statement that you want. The basic statement is:
select "tablename"
from tablename
where columnname = value
limit 1
Note that value may need to have single quotes around it. You can generate this with:
select concat('select "', c.table_name, '" ',
'from ', c.schema_name, '.', c.table_name, ' ',
'where ', c.column_name, ' = ', VALUE, ' '
'limit 1'
)
from information_schema.columns c
where c.table_name = TABLENAME and c.column_name = COLUMN_NAME;
To put all the statements in one long SQL statement, use:
select group_concat(concat('select "', c.table_name, '" as table_name',
'from ', c.schema_name, '.', c.table_name, ' ',
'where ', c.column_name, ' = ', VALUE, ' '
'limit 1'
) SEPARATOR ' union all '
)
from information_schema.columns c
where c.table_name = TABLENAME and c.column_name = COLUMN_NAME;
I would then just copy the resulting SQL statement and run it. If you like, you can add a prepare statement and run it dynamically.
as an example,
I have a table named T1 with columns (C1,C2), and I am searching for the value 'Needle'.
What this store procedure does is search through table names that starts with T and columns that starts with C, then loop through them and finds the value 'Needle'. It then returns the table_Schema,table_name,column_name and how many times the value 'Needle' is found within that column_name,table_name,table_schema combination.
see this sqlFiddle
CREATE PROCEDURE findDatabase(IN in_value varchar(50))
BEGIN
DECLARE bDone INT;
DECLARE _TableSchema VARCHAR(50);
DECLARE _TableName VARCHAR(50);
DECLARE _ColumnName VARCHAR(50);
DECLARE curs CURSOR FOR SELECT TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME FROM information_schema.columns WHERE TABLE_NAME LIKE "T%" AND COLUMN_NAME LIKE "C%";
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
DROP TEMPORARY TABLE IF EXISTS tblResults;
CREATE TEMPORARY TABLE IF NOT EXISTS tblResults (
id int auto_increment primary key,
tableSchema varchar(50),
tablename varchar(50),
columnname varchar(50),
timesFound int
);
OPEN curs;
SET bDone = 0;
REPEAT
FETCH curs INTO _TableSchema,_TableName,_ColumnName;
SET #found = 0;
SET #sql = CONCAT("SET #found = (SELECT COUNT(*) FROM ",_TableSchema,".",_TableName,
" WHERE ",_ColumnName,"='",in_value,"')");
PREPARE statement FROM #sql;
EXECUTE statement;
IF (#found > 0) THEN
INSERT INTO tblResults(tableSchema,tableName,columnName,TimesFound) VALUES (_TableSchema,_TableName,_ColumnName,#found);
END IF;
UNTIL bDone END REPEAT;
CLOSE curs;
SELECT DISTINCT TableSchema,TableName,ColumnName,TimesFound FROM tblResults;
DROP TABLE tblResults;
END//

Assigning a SQL result to variable from prepared statement in MySQL

I am creating a stored procedure in MySQL and need to assign the results of a SQL query to a variable. The problem is that in order to create the SELECT statement, I have to use the CONCAT() function because I am passing in parameters.
Well it appears you can't use variables within the CONCAT function. Any ideas on how I can achieve this? The procedure I am trying to write is below:
DELIMITER //
CREATE PROCEDURE `my_proc` (IN tbl VARCHAR(20), IN col VARCHAR(20), IN id INT)
BEGIN
DECLARE #myval VARCHAR(100);
SET #t1 =CONCAT('SELECT ',col,' FROM ',tbl,' INTO #myval WHERE id = ',id );
PREPARE stmt1 FROM #t1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END //
Executing this gives me a SQL syntax error.
The problem is the following line:
...
-- SET #t1 = CONCAT('SELECT ',col,' FROM ',tbl,' INTO #myval WHERE id = ',id );
SET #t1 = CONCAT('SELECT ', col, ' INTO #myval FROM ', tbl, ' WHERE id = ', id);
...
Check the documentation: 13.2.9.1. SELECT ... INTO Syntax.
Here is a SQL Fiddle with an example.
It is important to indicate the difference between 9.4. User-Defined Variables (#t1 and #myval) and 13.6.4.1. Local Variable Syntax DECLARE (as could be: myval and t1), are different variables, therefore, it is not necessary to declare:
-- DECLARE #myval VARCHAR (100);

Creating Dynamic Query in Stored Procedure MySQL

I have a Table and Rows in table like below
CREATE TABLE Areas(AreaName VARCHAR(255),
PinCode VARCHAR(255))
INSERT INTO Areas(AreaName, PinCode)
VALUES('Teynampet', '6000018'),
('Ramapuram', '6000089'),
('TNagar', '6000017'),
('Mylapore', '6000014'),
('Gopalapuram', '6000087')
I Wrote a SQL Procedure as Below
DROP PROCEDURE IF EXISTS mp_test;
CREATE PROCEDURE mp_test(IN pArea VARCHAR(255))
BEGIN
SET #Query = 'SELECT PinCode FROM Areas';
IF pArea != ''
THEN
SET #City = CONCAT(' WHERE AreaName = ', pArea);
END IF;
SET #Query = CONCAT(#Query, #City);
PREPARE stmt FROM #Query;
EXECUTE stmt;
END
When I Call the Procedure
CALL mp_test('Teynampet');
When i Execute i am Not getting the Desired result i.e is 600018
How can i build query dynamically in SP
Thanks for the Help
You're concatenating the pArea parameter into the SQL unquoted. That is, the content of #Query that you prepare for execution is:
SELECT PinCode FROM Areas WHERE AreaName = Teynampet
Since Teynampet is unquoted, it is parsed as a(n unknown) SQL identifier rather than a string. You should either:
quote it in your SQL:
SET #City = CONCAT(' WHERE AreaName = ', QUOTE(pArea));
pass it to the prepared statement as a parameter:
SET #City = CONCAT(' WHERE AreaName = ?');
SET #param = pArea;
and then:
EXECUTE stmt USING #param;
However, why use prepared statements here? Your procedure can be rewritten as a simple SELECT (which raises the question of whether you need to use a stored procedure at all):
CREATE PROCEDURE mp_test(IN pArea VARCHAR(255))
SELECT PinCode FROM Areas WHERE pArea IN (AreaName, '');
(Note that I'd recommend you use NULL instead of the empty string '', in which case the above test would be pArea IS NULL OR pArea = AreaName).

how to pass table name into a function?

is there any method how to make MySQL function that receives table name or field name ?
something like this :
CREATE PROCEDURE delete_row(the_id INT UNSIGNED , #table_name )
BEGIN
IF ....... THEN
BEGIN
DELETE FROM #table_name WHERE id = the_id ;
.............
END
END
I tested it with string (SET #table_name="table_name"), but it doesn't works.
declare varchar(max) #mySQL
set #mySQL = 'DELETE FROM ' + #tablename + 'WHERE id = ' + Convert(varchar, #the_id)
sp_executeSQL #mySQL
and to make this work on MySQL (as the commenters pointed out) it should look like this:
mysql> prepare stmt from -> 'DELETE FROM ' + #tablename + 'WHERE id = ' + Convert(varchar, #the_id)
mysql> execute stmt;