Mysql while with variable dynamic - mysql

I need to dynamically retrieve the variable in my while, but do not know if I'm using the correct way, in the code below I need to retrieve the table name to make the inclusion, but returns an error. This test is only an example, actually I will use this procedure to create a Trigger for the tables.
Ex:
DECLARE i INT DEFAULT 0;
DECLARE tb_name VARCHAR(8000);
SET #db_name = "test_ph";
SET #qtd_tables = (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = #db_name);
WHILE i < #qtd_tables DO
SET tb_name = (SELECT table_name FROM information_schema.tables WHERE table_schema = #db_name LIMIT i,1);
INSERT INTO tb_name(name, email) VALUES('test', 'test#test.com');
SET i = i + 1;
END WHILE;

Related

IF Exists then update in mysql

New to MySQL, need help in translating the next query to MySQL
If exists (select * from INFORMATION_SCHEMA.COLUMNS where table_name= 'MyTable' and column_name = 'MyColumn')
begin
update MyTable set MyColumn='' where Code=21
end;
Based on the comments posted on your question, here is a code snippet that should answer your need. It works by first checking if the column exists in INFORMATION_SCHEMA, and then dynamically building a SQL query that is prepared, then executed. It the column does not exists, a dummy query is executed instead of the UPDATE. I tested it in this db fiddlde.
SET #dbname = DATABASE();
SET #tablename = "my_table";
SET #columnname = "my_column";
-- check if the column exists
SELECT COUNT(*) INTO #cnt
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(table_name = #tablename)
AND (table_schema = #dbname)
AND (column_name = #columnname)
;
-- build a dynamic SQL statement
SET #preparedStatement = (SELECT IF(
#cnt > 0,
CONCAT("UPDATE ", #tablename, " SET ", #columnname, " = '' WHERE my_code = 21;"),
"SELECT 1"
));
-- run the statement
PREPARE updateIfExists FROM #preparedStatement;
EXECUTE updateIfExists;
DEALLOCATE PREPARE updateIfExists;

Check to see if tables are present in a database - stored procedure - MySQL

I want the user to input whatever database they want to check and whatever tables they want to check. For example the call would look like this:
call tableCheck('MyDatabase', 'table1 table20 table3')
So the procedure would check for those tables (space delimited). I have my code down below but I am having problem checking the other tables, it reads the first but not the second or third one. SO my code is not looping or not reading the next word.
PROCEDURE `tableCheck` (db VARCHAR(256), db_tables VARCHAR(256))
BEGIN
DECLARE tbl, tbls VARCHAR(256);
DECLARE c INT DEFAULT 0;
SET tbls = db_tables;
WHILE c = 0 DO
#split word
SET tbl = SUBSTRING_INDEX(tbls," ",1);
#go to next string
SET tbls = SUBSTR(tbls,LENGTH(tbl)+1);
#check every table
SELECT table_name AS 'Table Name'
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema=db AND table_name=tbl;
IF tbls = 0 THEN
SET c = 1;
END IF;
END WHILE;
END
I have given this link out a few times today...so maybe it will work for you too.
Convert a delimited string to a list of values
Using the dbo.fnArray function from that link you should be able to join on the INFORMATION_SCHEMA.TABLES like this:
create procedure dbo.spCheckTable #db varchar(256), #tbls varchar(8000)
as
begin
select *
from INFORMATION_SCHEMA.TABLES i
inner join dbo.fnArray(#tbls, ' ') t on i.TABLE_NAME = t.arrValue
where i.TABLE_CATALOG = #db
end
Now its a stored procedure

MySQL select from dynamic database and table query

Stored Proc Definition:
DECLARE dbName varchar(255);
DECLARE tableName varchar(255);
DECLARE fullPath varchar(255);
DECLARE conditions varchar(255);
SET dbName = idbname;
SET tableName = itablename;
SET fullPath = CONCAT("'",dbName,"'",'.',"'",tableName,"'");
SET checkExists = 0;
I am creating a stored proc where the dbname and tablename are dynamic, however I am stuck on the select aspect of this query.
I am trying to repalce the _test.user with values passed into the stored proc.
SELECT count(*) INTO checkExists FROM `_test`.`user` WHERE id = 1;
However this line throws an error
SELECT count(*) INTO checkExists FROM fullPath WHERE id = 1;
Error:
Procedure execution failed
1146 - Table 'dbname.fullpath' doesn't exist
I have also tried CONCAT() like this
set conditions = CONCAT('SELECT count(*) INTO ',checkExists, ' FROM ', fullPath, ' WHERE id=', 1);
However I can't figure out even how to use this in a select? Help is appreciated.
I like to do these modifications using replace(). Something like this:
replace(replace('SELECT count(*) INTO checkExists FROM `<dbname>`.`<tname>` WHERE id = 1',
'<tname>', v_tablename
), '<dbname>', v_databasename
)
You may also want to use v_fullpath somewhere. I'm not really sure what query you actually want to create.
I'm not sure why you have a variable called checkExists, when it seems to be the destination file. However, I would suggest that you prepend all your local variables with something to distinguish them from column names.

Output variable from dynamic SQL

I have an issue wen I try to output a value from a dynamic T-SQL Query inside of a stored procedure.
I try to execute the following and simply output a 1 if something was found:
SET NOCOUNT ON
DECLARE #returnValue int
DECLARE #Statement nvarchar(400)
set #Statement = 'SELECT #result=''1'' FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ''sourceTable''
AND COLUMN_NAME = #columnIN
AND TABLE_SCHEMA = ''dbo'''
exec sp_executesql #Statement,
N'#columnIN nvarchar(60),#result INT OUTPUT',
#columnIN = #column, #result=#returnValue OUTPUT
select #returnValue
This currently yields NULL. Does anyone have any idea what I'm missing?
Additional Information:
The column that I try to lookup is for example column1 . If I run the SQL query with ...AND CLOUMN_NAME = 'column1' ... I get a 1 back.
If I print the #column variable in the SP I get 'column1'.
#column is declared as an input variable with nvarchar(60) in the SP: PROCEDURE [dbo].[usp_checkColumn] (#column nvarchar(60), #result INT OUTPUT)
As per request the complete SP here:
Create PROCEDURE [dbo].[usp_checkColumn] (#column nvarchar(60), #result INT OUTPUT)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
DECLARE #returnValue int
DECLARE #Statement nvarchar(400)
set #Statement = 'SELECT #result=''1'' FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ''t_table''
AND COLUMN_NAME = #columnIN
AND TABLE_SCHEMA = ''dbo'''
exec sp_executesql #Statement, N'#columnIN nvarchar(60),#result INT OUTPUT', #columnIN = #column, #result=#returnValue OUTPUT
select #returnValue
return #returnValue
END
And here's how I call the SP:
DECLARE fcursor CURSOR
FOR
select FieldName
from t_fieldDefinition
OPEN fcursor
Fetch next from fcursor into #field;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #tmpField = '''' + #field + ''''
SET #field ='[' + #field + ']'
set #available = 0
exec usp_checkColumn #tmpField,#available OUTPUT
If I print the [#column] variable in the usp_checkColumn I do get the correct column inside of the ''. If I copy & paste the print of this variable and insert it into the query I get a 1 back, if I run the SP I get NULL(converted to 0 as NULL is not valid for the INT variable) back.
Here's the content of the t_fieldDefinition table:
FieldName ID
Source 5
column1 6
column2 7
Client 8
asd BSX 9
bsd 10
esd 11
esx 12
And here's the definition of the t_table table:
ID bigint Unchecked
Source varchar(250) Checked
column1 varchar(250) Checked
column2 nvarchar(100) Checked
Client varchar(10) Checked
asd varchar(250) Checked
[asd BSX] varchar(250) Checked
so that means that it should return 1 for all that are inside of the table definition and 0 for all others. Is it possible that the fields with a white space can be the issue? Although they work as well when you do it manually. It's not that I really have an option to change it but at least I would now the cause of the issue then.
I'm going to venture an answer on this.
I do not recommend using a cursor to go through each column just to test if the column exists in another table. If you insist on using a cursor, you could use a subquery to limit the results that you're cycling through to only the columns that don't exist in the other table, eliminating the need for the stored procedure that checks each individually (which by the way I think makes more sense as a user function):
DECLARE fcursor CURSOR
FOR
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
where table_name = 't_table' and not column_name in
(
SELECT COLUMN_Name FROM INFORMATION_SCHEMA.COLUMNS
where table_name = 't_fieldDefinition'
)
If your goal really is to alter the table to add any missing columns, then this can be improved by eliminating the cursor and outputting your results using FOR XML:
declare #sql varchar(max)
set #sql =
(
SELECT cast('ALTER TABLE t_fieldDefinition ADD [' + COLUMN_NAME + '] INT;' as varchar(max)) FROM INFORMATION_SCHEMA.COLUMNS
where table_name = 't_table' and not column_name in
(
SELECT COLUMN_Name FROM INFORMATION_SCHEMA.COLUMNS
where table_name = 't_fieldDefinition'
) FOR XML PATH ('')
)
print #sql
exec (#sql)

Something equivalent to "SELECT * FROM (SELECT table_name FROM...)"?

This query runs, but it produces the name of a table as a result, rather than actually selecting from that table.
SELECT T.*
FROM (SELECT tablename
FROM ListOfTables
WHERE id = 0) AS T
where ListOfTables contains id=0, tablename='some_table', I want to return the same result set as if I had written this directly:
SELECT * FROM some_table
Is there a native way to do this in MySQL 5, or do I have to do in in the application?
To do this in MySQL, you need to create a prepared statement which you can only create from a user variable:
SELECT #tn := tablename FROM ListOfTables WHERE id = 0;
SET #qs = CONCAT('SELECT * FROM ', #tn);
PREPARE ps FROM #qs;
EXECUTE ps;
You need to use dynamic SQL to get this result (the below code assumes SQL Server, I can't speak for other RDBMS').
declare #tableName varchar(100)
declare #query varchar(500)
select #tableName = tablename
from ListOfTables
where id = 0
select #query = 'select * from ' + #tableName
exec (#query)
Almost the same as #Shark's answer, except you also quote the name of the table to avoid syntax errors.
-- Using variables just for better readability.
DECLARE #Name NVARCHAR(4000)
DECLARE #Query NVARCHAR(4000)
-- Get the relevant data
SET #Name = QUOTENAME(SELECT tablename FROM ListOfTables WHERE id=0)
-- Build query
SET #Query = 'SELECT * FROM ' + #Schema + '.' + #Name + ''
-- execute it.
EXEC(#Query)