mysql-phpmyadmin create event get error - mysql

I am trying to add new event to rename a table in my DB use by phpmyadmine, and it will give me the errors :
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near SET #tablename = 'Today Raw Data';SET #newname = ' raw Data'; SELECT #query' at line3
my code is :
select #yesterday := date_sub(curdate(),interval 1 day);
SET #tablename = 'Today Raw Data';
SET #newname = ' raw Data';
SELECT #query := CONCAT('RENAME TABLE `', #tablename, '` TO `',#yesterday,#newname, '`');
PREPARE STMT FROM #query;
EXECUTE STMT;

CREATE TABLE alter (first_day DATE, last_day DATE);
How to fix it: Just because the word alter is reserved does not mean it cannot be used, it just has special requirements to use it as the MySQL engine is trying to call the functionality for the alter command. To fix the issue, you will want to surround the word with backticks ``, this is usually the button just to the left of the "1" button on the keyboard. The code block below shows how the code will need to look in order to run properly.
CREATE TABLE `alter` (first_day DATE, last_day DATE);
Missing Data
Sometimes data in the database is missing. This can cause issues when this data is required for a query. For example, if a database is built requiring an ID number for every student, it is reasonable to assume a query will be built to pull a student record by that ID number. Such a query would look like:
SELECT * from students WHERE studentID = $id
If the $id is never properly filled in the code, the query would look like this to the server:
SELECT * from students WHERE studentID =
www.google.com.tr/

Related

How append MySQL table name with today's date in format "-YYYY-MM-DD" with BASH

From the Linux CMD line, how would I append a MySQL table name with today's date in YYYY-MM-DD format. For example, if today's date is 4/13/18, it would change tablename to tablename-2018-04-13.
I believe I'm close with what I've tried after entering mysql from command line:
ALTER TABLE database.tablename RENAME database.tablename-$(date +%Y-%m-%d);
This generates an 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 '-$(date +%Y-%m-%d)' at line 1
You seem to be using a bash command substitution inside the MySQL client. That won't work, because SQL doesn't know anything about bash syntax like $().
Another problem is that you must use an identifier, not a string. The name of the table can't be an expression, it has to be fixed in your ALTER statement before it is parsed.
You could do this with PREPARE and EXECUTE:
mysql> SET #sql = CONCAT('ALTER TABLE database.tablename RENAME database.tablename_', DATE_FORMAT(CURDATE(), '%Y%m%d'));
mysql> PREPARE stmt FROM #sql;
mysql> EXECUTE stmt;
Note I changed your table name, because - is a special character in SQL identifiers. You can't normally use a table name that has - characters. You can if you put your table name in delimiters. MySQL's delimiters are back-ticks.
mysql> SET #sql = CONCAT('ALTER TABLE database.tablename RENAME database.`tablename-', DATE_FORMAT(CURDATE(), '%Y-%m-%d'), '`');
Then prepare and execute like before.
But this is needlessly complex, and you would need to remember to use back-ticks every time you want to use this table in a query.
It's much simpler to avoid using special characters in your table names.
set #sql = CONCAT('RENAME TABLE `tablename` TO tablename', DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%Y_%m_%d'));
prepare s from #sql;
execute s;
Updated based on #Anthony's comments. The sql command is tested;
All the answers and comments brought me to the answer that worked best for me. I ditched the -YYYY-MM-DD appending convention as it does nothing for me other than create problems, as highlighted by #Bill_Karwin above. This is the simple BASH command, very similar to the comment by #Anthony above, that works for me:
mysql database -e "ALTER TABLE table RENAME table_$(date +%Y%m%d)";
This renames table to (assuming for example if ran on 4/15/18) table_20180415.

How to use a variable with dynamic field names for ON DUPLICATE KEY in a trigger (MariaDB/MySQL)

I have hundreds of databases with some structurally identical (but over time changing) tables. Data of a certain table (from all DBS) should be copied into one central table ('ex_objects') in a central database ('db_central'; there are no pk conflicts). I've used a trigger in each DB for this purpose. But since the table structure is changing almost on a daily basis, it's a pain to update the fields in the ON DUPLICATE KEY part of the trigger's query. And someone could forget to modify the trigger after modifying the table structure. So I came across a possible solution to build that particular part of the query dynamically. This actually works on a script (PHP) basis, but I don't get the trigger done. I don't see what I am missing here.
BEGIN
DECLARE VAL_FIELDS TEXT;
SET VAL_FIELDS = (SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_central' AND TABLE_NAME = 'ex_objects');
-- SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") INTO VAL_FIELDS FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_central' AND TABLE_NAME = 'ex_objects';
-- SELECT #VAL_FIELDS := GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") INTO VAL_FIELDS FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_central' AND TABLE_NAME = 'ex_objects';
IF NEW.online = 1 THEN
INSERT INTO db_central.ex_objects
SELECT * FROM ex_objects WHERE id = NEW.id AND client_id = NEW.client_id AND NEW.online = 1
ON DUPLICATE KEY UPDATE VAL_FIELDS;
END IF;
END
I get the error that there's something wrong at ; END IF; END. Well, that means for me, that either the VAL_FIELDS variable after KEY UPDATE isn't recognized at all or the parser expects at least one equation (something like VAL_FIELDS = whatever). But in this case, it wouldn't solve my underlying problem at all.
The SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=v ... FROM INFORMATION_SCHEMA.C ... Query works well and results in something similar to id=values(id), xfield=values(xfield), yfield=values(yfield) (but with a few hundred fields, since the table is actually pretty huge).
The full error: SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
END IF;
END' at line 10
You must build the SQL using CONCAT, etc, then prepare and execute it. There is no 'interpolation'.
Since it is a TRIGGER, that won't work.
However, since a TRIGGER applies to a particular table, you may as well simply spell out the query, not construct it. You have most of what it takes to manually get the query generated for you (SELECT ... I_S ...). Add some more columns for OLD.col to fill out the thing; viola, you have the query that you need.

MySQL, How to pass #var after ADD keyword?

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.

MySQL create a dynamic table name in a Join statement

long time user, first time poster.
I have 2 tables;
a1_watchlists {id(PK),name,date}
a1_watchlist {id(PK),watchlists_id(FK(a1_watchlists.id)),company_name,asx_code,date}
I also have 2000 other tables that have been created with the name 'asx_'+[asx_code] (where asx_code is pulled from another table)
this table looks like;
asx_[asx_code] {date(PK),open,high,low,close,volume}
I want to select all from a1_watchlists and a1_watchlist and then select the latest date from the asx_[asx_code] table using the value from a1_watchlist.asx_code to generate the [asx_code] part of the table name.
The problem I have is that I want to use the value from a1_watchlist.asx_code as the table name prepending the string 'asx_' to this first.
Closest I have been able to get is;
DECLARE #TableName VARCHAR(100)
SELECT *
FROM a1_watchlist AS wl
JOIN a1_watchlists AS wls
ON wls.id = wl.watchlists_id
SET #TableName = 'asx_' + wl.asx_code
INNER JOIN (SELECT MAX(date),open,high,low,close,volume,amount_change,percent_change FROM #TableName)
This currently give the 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 'DECLARE #TableName VARCHAR(100)
SELECT *
FROM a1_watchlist AS wl
' at line 1
The expected colums I need in the final result would be:
wl.id,wl.watchlists_id,wl.company_name,wl.asx_code,asx_[asx_code].date,asx_[asx_code].open,asx_[asx_code].high,asx_[asx_code].low,asx_[asx_code].close,asx_[asx_code].volume
Let me know if you require more information.
I'm not going to speak to what to do in the case where you have 2000+ tables that start with asx+ some code... (i live in a town with multiple bridges) or even whether what you're doing is the best way to get where you want to go. BUT, it does look like you're attempting to concatenate things together and create a dynamic statement. If that sounds right, then I'd recommend you look into prepared statements. Like the following. Hope this helps.
DELIMITER $$
DROP PROCEDURE IF EXISTS prRetrieveAllFromTable$$
CREATE PROCEDURE prRetrieveAllFromTable(tableName VARCHAR(64))
BEGIN
SET #s = CONCAT('SELECT * FROM ',tableName );
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
CALL prRetrieveAllFromTable('calendar');
http://dev.mysql.com/doc/refman/5.5/en/sql-syntax-prepared-statements.html
How To have Dynamic SQL in MySQL Stored Procedure

SQL: convert all columns to VarChar(255)

After some searching here on stackoverflow and on the web, I couldn't find the answer to my question. I'm not a real SQL talent, but I'm trying to covert all the columns in my table to varchar (255). It has about 600 columns which are all varchar, but the size limit varies. I would like them all to be 255. Is there a way to not having to do this manually? I work with MySQL.
Thanks!
You need to generate the alter table statement by pulling the data from the database.
select 'alter table MyTableName modify column ' + column_name + ' varchar(255);'
from information_schema where table_name = 'MyTableName'
And then paste the results of this command into the query window and run it -- making sure it does what you want it to do. Do a backup first.
Or you could make one big alter statement (if MySql wouldn't choke on it) by replacing the semicolon with a comma.
This isn't what you really need to do. You have something more important to do: NORMALIZE YOUR DATABASE
Now, It's impossible that you have a normalized table with 600 columns. Split your entities in that table correctly, following at least the 3rd normal form rules. After that, you'll have a much better database which is easier to mantain.
To do this, you'll need to drop your current table, therefore, you don't need to change all the types to varchar(255) because you'll fix them during the creation of other tables.
This would be a good start to read: http://en.wikipedia.org/wiki/Database_normalization (thanks to #Tim Schmelter from question's comments)
First of all as mentioned by others you better off normalize you data.
In the meantime you can achieve your goal with dynamic SQL like this
DELIMITER $$
CREATE PROCEDURE change_to_varchar255(IN _tname VARCHAR(64))
BEGIN
SET #sql = NULL;
SELECT GROUP_CONCAT(
CONCAT_WS(' ', 'CHANGE', COLUMN_NAME, COLUMN_NAME, 'VARCHAR(255)'))
INTO #sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = _tname
AND DATA_TYPE = 'varchar'
AND CHARACTER_MAXIMUM_LENGTH < 255
AND TABLE_SCHEMA = SCHEMA();
SET #sql = CONCAT_WS(' ', 'ALTER TABLE', _tname, #sql);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Sample usage:
CALL change_to_varchar255('table1');
Here is SQLFiddle demo
If you are using PhpMyAdmin or other, you can also click on the button to modify the table.
When you are on the web page, press Ctrl+Shift+J under Windows or Cmd+Opt+J under Mac to open the console window in the Chrome Developer tools. Now enter the following command to replace all occurrences of the number 255 with 100 :
document.body.innerHTML = document.body.innerHTML.replace(/255/g, "100").
Finally, click on the button to execute the query.