I want to dynamically create table from my program with columns name and table name given by me through my program. so i want to pass my variable to the stored procedure but error occurs as i do like this
create procedure maketable
#name varchar(50),
#roll int
as
begin
create table new (#name, #roll)
end
error is as follow
Msg 102, Level 15, State 1, Procedure maketable, Line 7
Incorrect syntax near '#name'.
You're out of luck, MySQL stored procedures can not contain dynamic SQL, and the variable implementation can't be used how you're trying to use it.
Because you know all of the column information in your calling code, is there a specific reason you can't just issue the CREATE TABLE directly from your code? That would be the most straightforward way to get this done. (Mind you, having non-temporary tables spring into existence on demand is probably a bad, bad idea...)
Here's a start - this creates a table with one field so you should be able to finish it off:
DROP PROCEDURE IF EXISTS maketable;
delimiter //
CREATE PROCEDURE maketable (IN table_name varchar(50), IN field1Name varchar(50), IN field1Type varchar(50))
BEGIN
SET #s = CONCAT('CREATE TABLE ', table_name, '(', field1Name, ' ', field1Type, ')');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
END//
delimiter ;
CALL maketable('tst', 'id', 'INT');
Related
DELIMITER $$
CREATE PROCEDURE prepared_return_value(IN columnName varchar(20), IN tableName varchar(20), IN rowIndex varchar(10))
BEGIN
SET #columnName = '';
SET #columnName = CONCAT('Select distinct ',columnName ,' from ', tableName, ' LIMIT ', rowIndex, ',', '1', ';');
-- SELECT #columnName;
PREPARE stmt FROM #columnName;
EXECUTE stmt;
END $$
DELIMITER ;
So, i'm trying to dynamic pivoting a table using prepared statements to return the unique value of the rows and use it to alter a table.
But for that, i need to be able to store the returned row value, so i can use it in another prepared statement as the column name.
Apparently i can't store the value from the execution of prepared statement neither from a procedure.
I've tried lot of things by know, but none seemed to work, só... any hint on that?
The Varoable is session bound, so you can be used after the procedure has run .
SELECT #columnName
direct after the running outside if the procedure.
another option s to use an OUT Parameter besides the IN
Ypu would run
CALL return_value(columnName, tableName, rowIndex, #columnName)
And the crete procedure wil look like
CREATE PROCEDURE prepared_return_value(IN columnName varchar(20), IN tableName varchar(20), IN rowIndex varchar(10), OUT myoutput TEXT
Still what you are doing is highly problematic as it could be used for sql injection, so you should white list colu,nname an Tablename
I'm trying to create a store procedure to add a column on a table.
when i use this code(like below),I want to create a column with name like 'newColumn' that I can name when I call procedure. But when I call procedure the column added but not with my name newColumn but with column name x!!
Thank you.
DELIMITER //
CREATE PROCEDURE addColumn(x varchar(20))
BEGIN
alter table proc
add column x varchar(20) not null;
END //
DELIMITER ;
call addColumn('newColumn');
Form the query using concat of the various parts and execute it.
CREATE PROCEDURE addColumn(x varchar(20))
BEGIN
SET #STMT = CONCAT("alter table proc add column ", x, " varchar(20) not null");
PREPARE S FROM #STMT;
EXECUTE S;
DEALLOCATE PREPARE S;
END
But as mentioned in comments, this is dangerous - it can lead to SQL Injection attacks and other problems. At the very least, please sanitize x as much as possible.
I am trying to create a new SQL procedure and am getting a syntax error. I am not the greatest with SQL so I am sure I have an error in there somewhere. Can someone tell me what is wrong with it? thanks for any help.
create PROCEDURE `p_provider_get_distributors_by_sort`(varOffset INT(11), varSortName varchar(50), varSortDirection varchar(6))
BEGIN
SET #st := concat('(SELECT id FROM distributor WHERE status = "AC") ORDER BY 'varSortName, varSortDirection' LIMIT 100 OFFSET ', varOffset);
PREPARE stmt FROM #st;
EXECUTE stmt;
END //
You missed lot of things in your sp
first of all, You have to add prefix '#' with all your parameters
Secondly, You must have to declare your #st object
I've written a stored procedure. It's working fine except taking the table name as input parameter.
Let see my proc in MySQL:
DELIMITER $$
USE `db_test`$$
DROP PROCEDURE IF EXISTS test_proc$$
CREATE DEFINER=`root`#`localhost`
PROCEDURE `test_proc`(IN serviceName VARCHAR(10),IN newsInfoTable VARCHAR(100))
BEGIN
SELECT COUNT(*) FROM newsInfoTable WHERE newsServiceName=serviceName;
END$$
DELIMITER ;
Stored procedure calling parameters:
USE db_test;
CALL test_proc('abc','tbl_test_news');
Here the service name parameter is working fine. But if I include the newsInfoTable variable as table input parameter then a error shows.
Table 'db_test.newsinfotable' doesn't exist
Why does this happen only for table parameter? How can I retrieve from this error or
How I pass a table name into a stored procedure as a parameter?
An SP cannot be optimized with a dynamic table name, so many DBs, MySQL included, don't allow table names to be specified dynamically.
One way around this is to use Dynamic SQL.
CREATE DEFINER=`root`#`localhost` PROCEDURE `test_proc`(IN serviceName VARCHAR(10),IN newsInfoTable VARCHAR(100))
BEGIN
SET #sql = CONCAT('SELECT COUNT(*) FROM ',newsInfoTable,' WHERE newsServiceName=?;');
PREPARE s1 from #sql;
SET #paramA = serviceName;
EXECUTE s1 USING #paramA;
END$$
You can use EXECUTE IMMEDIATE for a "less is more" solution (for me, less code = good)
CREATE PROCEDURE test_proc(IN serviceName VARCHAR(10), IN newsInfoTable VARCHAR(100))
BEGIN
EXECUTE IMMEDIATE CONCAT('SELECT COUNT(*) FROM ',newsInfoTable,' WHERE newsServiceName=''', serviceName, '''');
END
that part of a query cannot be dynamic.
you may consider implementing as a string that is executed dynamically at runtime
Although may not be what you want, alternatively, can consider to use conditionally if and prepare the statement.
DELIMITER $$
CREATE PROCEDURE select_count(IN table_name VARCHAR(20))
BEGIN
IF table_name = 'xxx' THEN
SELECT * FROM xxx;
ELSEIF table_name = 'yyy' THEN
...
ENDIF
END$$
I have a need to sync auto_increment fields between two tables in different databases on the same MySQL server. The hope was to create a stored procedure where the permissions of the admin would let the web user run ALTER TABLE [db1].[table] AUTO_INCREMENT = [num]; without giving it permissions (That just smells of SQL injection).
My problem is I'm receiving errors when creating the store procedure. Is this something that is not allowed by MySQL?
DROP PROCEDURE IF EXISTS sync_auto_increment;
CREATE PROCEDURE set_auto_increment (tableName VARCHAR(64), inc INT)
BEGIN
ALTER TABLE tableName AUTO_INCREMENT = inc;
END;
To extend on the discussion on the comments on Chibu's answer... yes, you can use prepared statements. But you got to use CONCAT to create the sentence instead of using PREPARE ... FROM ....
Here is a working solution:
DROP PROCEDURE IF EXISTS set_auto_increment;
DELIMITER //
CREATE PROCEDURE set_auto_increment (_table VARCHAR(64), _inc INT)
BEGIN
DECLARE _stmt VARCHAR(1024);
SET #SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT = ', _inc);
PREPARE _stmt FROM #SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END//
DELIMITER;
I've learned this form the article Prepared Statement Failure by Michael McLaughlin.
The problem seems to be that you need to change the delimiter. It thinks that the Alter table line is the end of the function. Try this:
DROP PROCEDURE IF EXISTS sync_auto_increment;
DELIMITER //
CREATE PROCEDURE set_auto_increment (tableName VARCHAR(64), inc INT)
BEGIN
ALTER TABLE tableName AUTO_INCREMENT = inc;
END//
DELIMITER ;
Sometimes mysql is still picky about letting you use stored procedures, so you can do try this if you still can't run it:
DROP PROCEDURE IF EXISTS sync_auto_increment;
DELIMITER //
CREATE PROCEDURE set_auto_increment (tableName VARCHAR(64), inc INT)
DETERMINISTIC
READS SQL DATA
BEGIN
ALTER TABLE tableName AUTO_INCREMENT = inc;
END//
DELIMITER ;
I think you'll find you can't put Data Definition Language statements into a stored procedure. A possible exception would be CREATE TEMPORARY TABLE. I have searched the MySQL manual for more information on that point; it says the stored procedure may contain a statement_list, but nowhere defines what that means. But I think that's the case.