Can mysql cli check a file without committing it? - mysql

I have sql in a file, which contains a number of statements. How can I get mysql to check the validity of the sql without executing it?
Something like
mysql --check-only input.sql
At a minimum, I need syntax to be checked.
Ideally, it would also attempt to e.g. insert data and check constraints. Basically wrapping the whole file in an implicit transaction which is automatically rolled-back.
Can mysql CLI do this?

I suggest to use the following, as you seem to be okay with using transactions:
mysql --init-command="SET autocommit=0;BEGIN;" < input.sql
What this will do is it will just start a transaction, process the SQL inside input.sql (including checks on syntax and inserts). Then, the process will finish without a COMMIT; being issued which will have the server rollback the whole thing.

Related

How to update stored procedures in multiple databases in mysql

I am very new to mysql and I have I a situation where I need to update all my stored procedure in all my database. for example I have 10 database just say:
client_1,client_2,client_3,.....client_10.
Every database have same stored procedure just say:
proc_1,proc_2,proc_3,proc_4.
So if I made any changes to one of my stored procedure then it should get updated in all other database So that I don't have to do it manually.
I know the similar question have been asked but I am looking for some different approach. So what I want is some kind of mysql query or something like that in which we will pass the name of the database like:
client_1, client_3, client_8
and changes will only made to this databases.
I am using heidiSql- 10.2 with MySQL 5.6.
Thanks.
I am not entirely sure what you are wanting to do but I think you want something like this. First save the definition of your stored procedure to a file. Make sure it doesn't contain an schema references like client1.tableA. You want it to be able to run in any copy of your schema correctly. Be sure to follow the syntax rules defined by MySQL
Defining Stored Programs
Then once the stored procedure is saved you can use the mysql command line to run it for each client you want to update.
You would first connect to the database server using the mysql command line. Then issue a USE command to activate the first client database. Then run the script using the SOURCE command. See MySQL Batch Commands Then repeat for each client.
USE client1;
source c:\temp\storedProcedure.sql
USE client2;
source c:\temp\storedProcedure.sql
If this is not exactly what you needed hopefully it gives you some ideas to get you what you need.
Note that you could do the connection to the database and execute these commands via batch file instead of manually if you wanted to.
There are no statements in MySQL that create/drop/alter multiple procedures at once. You can only change one procedure at a time.
You can write an SQL script that includes a series of statements. But it's up to you to write that script.
You may write some script in Python (or other favorite language) that outputs the SQL script.
I don't know HeidiSQL, but I doubt it has any facility to apply the same change to many procedures. Nor does any other MySQL client that I'm aware of.

How can I track the execution of `source filename` command in mysql

How can I track the execution of source filename command in mysql so that I can have the filename and path of sql scripts that's been run. Google didn't help or may be I didn't use the right keyword.
So when I execute source ./test/file.sql (without errors preferably)
I want an entry in "source_history" table with current_time,filename(along with path) which I can do if I could figure how to track.
It'd be of great help if anyone could help me in keeping track of the command source.(Something like a trigger event for insert or update on table)
(may be, tracking all command in that sense and then while exiting mysql, get the query history and check for source)
Hope that makes sense.
Thanks in advance.
The problem is that the source command is not a MySQL command, it is a command in MySQL's command line interface, which is also named MySQL.
CLI only passes the sql commands within the file to the MySQL server, therefore the server cannot be aware of the exact file used for executing the command.
MySQL own documentation the source command (see the link above) suggests the most obvious solution:
Sometimes you may want your script to display progress information to
the user. For this you can insert statements like this:
SELECT '<info_to_display>' AS ' ';
So, the simples way is to create a table with fields for path, event type (start / stop) and a timestamp and add insert statements to the start and end of each sql file that log the start and the end of each batch and supply the name of the file hard coded in the insert statements. You may want to create a script that adds these commands to the sql files.
Alternative is to create a batch file that receives a path to an .sql file in a parameter, invokes MySQL's CLI, logs the start of the batch process in mysql, launches the .sql file, and then logs the completion of the batch in MySQL.

Mysql Client Option: How to Use –comments in mysql client

I am learning mysql client program.I was trying to understand client option -comments.I have seen document regarding this in mysql MySQL 5.6 Reference Manual.
But I didn't get any code example to illustrate this option.Please tell me how to Enter this command in correct syntax.Also it would more clear to me if i get opportunity to see this example on any online mysql terminal.Thanks
MySQL comments are lines that begin with #, like Unix shells. It's as simple as that. Example:
# this is a comment describing the next line which select all data from the `users` table
SELECT * from `users`;
The -comments argument to the mysql command line client is used to tell it to send the comments to the server which is not done by default. These comments are later visible in the query logs and stored procedures (which is the simplest way to see it in action).

Catch error in MYSQL

I want to implement a batch MySQL script to do something in a database. The thing is that, for each master id that I have I want to insert 4 tuples. But this tuples should be added in a transaction which means if one of these 4 tuples is failed the transaction should be rollback. Then I need to have some catching mechanism to capture that the query is failed. I CAN ONLY USE PURE MYSQL neither PHP, nor PERL etc. Even I cannot create any store procedure to do that. In Microsoft SQL Server there is ##error variable that solved my problem but in MYSQL we do not have any system variables showing the error code.
how can I do that?
Cheers,
This is an ugly workaround, but it worked for me when I was trying to import a batch of SQL queries and wrap the entire thing within a transaction, so that I could roll back if any of the SQL queries errored.
Since the size of the batch was massive, a SQL procedure with condition handler was not an option either.
You have to do this manually, so it really isn't a solution unless you are batching:
First, make sure your entire batch is stored in an SQL file. The SQL file should only contain the batch queries, and no transaction control queries.
Then start up a MySQL command line client and type in transaction commands manually:
mysql> SET AUTOCOMMIT = 0;
mysql> START TRANSACTION;
Then tell the command line client to run the batch file:
mysql> SOURCE path/to/file.sql
After that you can simply manually COMMIT; or ROLLBACK; depending on how happy you are with the result of your queries.
This is such a kludge, though. Anyone have a better approach?

When a new row in database is added, an external command line program must be invoked

Is it possible for MySQL database to invoke an external exe file when a new row is added to one of the tables in the database?
I need to monitor the changes in the database, so when a relevant change is made, I need to do some batch jobs outside the database.
Chad Birch has a good idea with using MySQL triggers and a user-defined function. You can find out more in the MySQL CREATE TRIGGER Syntax reference.
But are you sure that you need to call an executable right away when the row is inserted? It seems like that method will be prone to failure, because MySQL might spawn multiple instances of the executable at the same time. If your executable fails, then there will be no record of which rows have been processed yet and which have not. If MySQL is waiting for your executable to finish, then inserting rows might be very slow. Also, if Chad Birch is right, then will have to recompile MySQL, so it sounds difficult.
Instead of calling the executable directly from MySQL, I would use triggers to simply record the fact that a row got INSERTED or UPDATED: record that information in the database, either with new columns in your existing tables or with a brand new table called say database_changes. Then make an external program that regularly reads the information from the database, processes it, and marks it as done.
Your specific solution will depend on what parameters the external program actually needs.
If your external program needs to know which row was inserted, then your solution could be like this: Make a new table called database_changes with fields date, table_name, and row_id, and for all the other tables, make a trigger like this:
CREATE TRIGGER `my_trigger`
AFTER INSERT ON `table_name`
FOR EACH ROW BEGIN
INSERT INTO `database_changes` (`date`, `table_name`, `row_id`)
VALUES (NOW(), "table_name", NEW.id)
END;
Then your batch script can do something like this:
Select the first row in the database_changes table.
Process it.
Remove it.
Repeat 1-3 until database_changes is empty.
With this approach, you can have more control over when and how the data gets processed, and you can easily check to see whether the data actually got processed (just check to see if the database_changes table is empty).
you could do what replication does: hang on the 'binary log'. setup your server as a 'master server', and instead of adding a 'slave server', run mysqlbinlog. you'll get a stream of every command that modifies your database.
step in 'between' the client and server: check MySQLProxy. you point it to your server, and point your client(s) to the proxy. it lets you interpose Lua scripts to monitor, analyze or transform any SQL command.
I think it's going to require adding a User-Defined Function, which I believe requires recompilation:
MySQL FAQ - Triggers: Can triggers call an external application through a UDF?
I think it's really a MUCH better idea to have some external process poll changes to the table and execute the external program - you could also have a column which contains the status of this external program run (e.g. "pending", "failed", "success") - and just select rows where that column is "pending".
It depends how soon the batch job needs to be run. If it's something which needs to be run "sooner or later" and can fail and need to be retried, definitely have an app polling the table and running them as necessary.