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;
Related
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.
I have mysql DB with incremental table names (ie. table1, table2, table3, tablen). Somewhere along the way this incrementation has skipped a few and there are gaps. I want to execute a script which will create the table with the correct table name when the loop finds a missing table. So something like..
for i=1 to 100
create table if not exists 'tablei'
***TABLE FIELD DECLARATIONS***
end
Any help much appreciated.
Something like (might need a few MySql syntax twiddles)
Declare #loopvar int
Declare #sql VarChar(8000)
Declare #table_definition VarChar(8000)
Set #table_definition = '(SomeField int null)'
Set #loopvar = 1
While #loopVar < 100
begin
set #sql = 'Create Table if not exists TableName' + Convert(VarChar(3),#loopvar) + #table_definition
exec(#sql)
set #loopvar = #loopvar + 1
end
should do it.
an answer with all the "MySql syntax twiddles":
DELIMITER //
CREATE PROCEDURE missing_tables(n INT)
BEGIN
WHILE n > 0
DO
SET #sql = CONCAT('create table if not exists table', n, ' (value INT)');
PREPARE cmd FROM #sql;
EXECUTE cmd;
DEALLOCATE PREPARE cmd;
SET n = n - 1;
END WHILE;
END; //
DELIMITER ;
CALL missing_tables(5);
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?
I'm trying run this procedure with generic parameters.
If I can't delete because some foreign key, it should update the row.
But when I execute it, still running forever and don't complete the process, any Idea?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[stp_Batch_Registros_Desativados_Excluir]
#table_name VARCHAR(100),
#id int
AS
BEGIN
DECLARE #column VARCHAR(100),
#sql VARCHAR(300);
SET #column = (SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMNPROPERTY(OBJECT_ID(TABLE_NAME),COLUMN_NAME,'IsIdentity') = 1
AND TABLE_NAME = #table_name);
BEGIN TRY
select #sql = 'DELETE ' + #table_name + ' WHERE ' + #column + ' = ' + CONVERT(VARCHAR,#id);
exec(#sql);
END TRY
BEGIN CATCH
select #sql = 'UPDATE ' + #table_name + ' SET fg_excluido = 2 WHERE ' + #column + ' = ' + CONVERT(VARCHAR,#id) ;
exec(#sql);
END CATCH;
END
This seems to work fine for me. Do you have triggers, cascading foreign keys, etc.?
USE tempdb;
GO
CREATE TABLE dbo.fooblat1
(
id INT IDENTITY(1,1) PRIMARY KEY,
x VARCHAR(1),
fg_excluido TINYINT NOT NULL DEFAULT 1
);
CREATE TABLE dbo.fooblat2
(
blatid INT NOT NULL FOREIGN KEY REFERENCES dbo.fooblat1(id)
);
INSERT dbo.fooblat1(x) SELECT 'a';
INSERT dbo.fooblat2 SELECT SCOPE_IDENTITY();
INSERT dbo.fooblat1(x) SELECT 'b';
GO
Then:
CREATE PROCEDURE [dbo].[proc]
#table_name VARCHAR(100),
#id INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #column NVARCHAR(100),
#sql NVARCHAR(MAX);
SELECT #column = name
FROM sys.columns
WHERE [object_id] = OBJECT_ID(#table_name)
AND is_identity = 1;
BEGIN TRY
SET #sql = 'DELETE [' + #table_name
+ '] WHERE [' + #column + '] = '
+ CONVERT(VARCHAR(12),#id);
EXEC sp_executesql #sql;
END TRY
BEGIN CATCH
SET #sql = 'UPDATE [' + #table_name
+ '] SET fg_excluido = 2 WHERE '
+ #column + ' = ' + CONVERT(VARCHAR(12),#id);
EXEC sp_executesql #sql;
END CATCH;
END
GO
Then:
EXEC [dbo].[proc] 'fooblat1', 1; -- should update
GO
EXEC [dbo].[proc] 'fooblat1', 2; -- should delete
GO
SELECT * FROM dbo.fooblat1;
GO
Cleanup:
DROP PROC [dbo].[proc];
DROP TABLE dbo.fooblat2;
DROP TABLE dbo.fooblat1;
GO
I have a stored procedure, and I would like to assign the number of rows of that table to a variable and later use that variable.
I am calling the procedure like:
EXEC TEST.dbo.myProc nameOfTable
The procedure is something like:
CREATE PROCEDURE myProc #table_name varchar(1024) AS
BEGIN
DECLARE #Nval INT
/* SOME INSTRUCTIONS */
SELECT #Nval = COUNT(*) FROM #table_name
END
When executing I am getting an error:
Msg 156, Level 15, State 1, Procedure nLQ, Line 57
Incorrect syntax near the keyword 'FROM'.
How would I assign the variable #Nval?
You can't parameterise a table name like that, FROM #table_name. Only way is to execute dynamic TSQL.
Before you do that, read: The Curse and Blessings of Dynamic SQL
try this
ALTER PROCEDURE [dbo].[sp_tablenametest]
#table_name varchar(50),
#PMId int,
#ValueEq int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #cmd AS NVARCHAR(max)
SET #cmd = N'SELECT * FROM ' + #table_name +
' WHERE Column1 = ''' + #PMId + '''' +
' AND Column2= ''' + #ValueEq + ''''
EXEC sp_executesql #cmd
END