I want to set the auto_increment value for each column by first finding the max id value.
I am referencing the code from this SO question.
The mysql docs for prepared statements show a similar format, so I am confused.
When I try running the prepare statement I get a failure. Why?
Below is the output when I try to prepare a regular statement and then when I try to prepare the auto_increment statement with a '?' for binding later.
mysql> PREPARE stmt1 FROM 'ALTER TABLE user AUTO_INCREMENT=2';
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> PREPARE stmt1 FROM 'ALTER TABLE user AUTO_INCREMENT=?';
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 '?' at line 1
An alternative would be
set #alter_statement = concat('alter table user auto_increment = ', #value);
prepare stmt1 from #alter_statement;
execute stmt1;
deallocate prepare stmt1;
For some reasons it seems many people are experiencing a syntax error when using prepare with ?.
My guess is that it fail because the given value will be replaced with the value, between two single quotes (this is just a guess though).
Related
First I create my table with one text column in 5.6.34 - MySQL Community Server (GPL) like so :
CREATE TABLE `$_query_test`.`t1` ( c1 TEXT NOT NULL ) ENGINE = InnoDB;
Then I execute:
SET #var = 321; INSERT INTO `t1` (c1) VALUES (#var);
I get one entry with a value of 321 as expected, but when i execute:
SET #var = '_string_';
ALTER TABLE `t1` ADD #var TEXT;
I get an error
#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 '#var TEXT' at line 1
What is the proper syntax to do something like this? I have searched far and wide and so far got nothing on this.
The answer is that you cannot substitute an sql variable in place of an identifier (e.g. field name, table name, etc). Period.
What you can do is to create the full sql statement as a string either on application level or in mysql with the identifier already substituted and you execute the full statement.
In mysql you can do this via prepared statements:
PREPARE stmt1 FROM CONCAT('ALTER TABLE `t1` ADD ', #var, ' TEXT');
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
You can use variables for values but not field names. You will need to do that with whatever server language you are using before composing the alter table.
I need to choose a table according to an instruction. But if I use a variable to store the name of the table, MySQL returns error 1064.
SET #eligetabla ='convenios';
select * from #eligetabla;
How can I use a variable for a table following the from clause?
Not that I think this is a particularly fantastic idea, and its quite the pain, but you can do this:
SET #eligetabla='convenios';
SET #sql=CONCAT("SELECT * FROM ", #eligetabla);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
You may as well be choosing the table application side and building your query there, tho.
I was testing out MySQL's PREPARE stmt FROM preparable_stmt; functionality in a stored procedure and decided to try out control blocks, starting with IF:
DELIMITER $$
CREATE PROCEDURE `testif`(t TEXT) BEGIN
DECLARE q TEXT;
SET #q:=CONCAT("IF (SELECT COUNT(*) FROM ", t, ")>5 THEN");
PREPARE query FROM #q; EXECUTE query;
DEALLOCATE PREPARE query;
SELECT "That's a nice table!";
INSERT INTO ... #and other behaviour other than SELECT
SET #q:="END IF";
PREPARE query FROM #q; EXECUTE query; DEALLOCATE PREPARE query;
END$$
Since it was being executed in the context of a stored procedure, I kind of expected this to work. Instead, when I CALL testif("t1");, I get this syntax error:
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 (SELECT COUNT(*) FROM t1)>5 THEN' at line 1
which I would get if I ran the query outside of the procedure.
For the record, I know how to make this query work without PREPAREing the IF clause directly. My question is purely out of curiosity, since I'm used to how eval-like functions work in other programming languages (where it executes the string as if it were hard-coded on that line). Setting variables and most other things work with PREPARE, but then again, they'd work outside of the procedure as well. Why doesn't this?
I'm trying to rename a list of tables using a constant prefix defined as a #var:
SET #p='newprefix_';
RENAME TABLE `oldprefix_tablename1` TO CONCAT(#p, 'tablename1');
RENAME TABLE `oldprefix_tablename2` TO CONCAT(#p, 'tablename2');
This syntax is wrong, but I see that:
SELECT CONCAT(#p, 'tablename'); //outputs newprefix_tablename
What's the correct way/syntax to use here?
You can't do it directly the way you are trying. As the manual says (http://dev.mysql.com/doc/refman/5.1/en/user-variables.html)
User variables are intended to provide data values. They cannot be
used directly in an SQL statement as an identifier or as part of an
identifier, such as in contexts where a table or database name is
expected, or as a reserved word such as SELECT.
You have to use prepared statements:
SET #p = 'newprefix_';
SET #s = CONCAT('RENAME TABLE `oldprefix_tablename1` to ', #p, 'tablename1');
PREPARE stmt FROM #s;
EXECUTE stmt;
I'm trying to create a prepared statement in MySQL that takes in a single parameter. When I try this on the command line I get a syntax error. However, when there are no variables in my prepared statement, I am able to create them fine. Below is a copy and paste of what I am seeing at the MySQL command prompt:
mysql> PREPARE state_name FROM "select * from ? limit 1";
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 '? limit 1' at line 1
mysql> PREPARE state_name FROM "select * from documents limit 1";
Query OK, 0 rows affected (0.00 sec)
Statement prepared
The version of MySQL I'm using is 5.0.77-log.
Is there a syntax error I'm not seeing? And are there any config parameters I have to set in order to get prepared statements to work?
You can't pass in table names as prepared statement parameters, I'm afraid, neither can you pass columns to group or sort by. The only thing you can parametrize are fields in where clauses or for updates:
PREPARE state_name FROM "select * from documents where id = ?";
PREPARE state_name FROM "update documents set field = ? where id = ?";
If you want to create a single prepare statement and use it for more than one table, you cand actually create a variable for every table, and then create the statement using this variable, as the MySQL manual explain it :
mysql> USE test;
mysql> CREATE TABLE t1 (a INT NOT NULL);
mysql> INSERT INTO t1 VALUES (4), (8), (11), (32), (80);
mysql> SET #table = 't1';
mysql> SET #s = CONCAT('SELECT * FROM ', #table);
mysql> PREPARE stmt3 FROM #s;
mysql> EXECUTE stmt3;
+----+
| a |
+----+
| 4 |
| 8 |
| 11 |
| 32 |
| 80 |
+----+
mysql> DEALLOCATE PREPARE stmt3;