I have a problem launching MySQL script from shell. I assign a value to my variable ${x}, using filename. So I have to launch a MySQL script using this variable. I would like to launch script without insert all MySQL code in shell (is too long) but using:
mysql -h localhost -uuser -ppsw DB < script.sql
My tentatives are:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x}; source script.sql"
mysql -h localhost -uuser -ppsw DB -e "set #x=${x};"
mysql -h localhost -uuser -ppsw DB< script.sql
But not work for me. Could you help me?
I was surprised that your first solution didn’t work:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x}; source script.sql"
Analysis
source is a MySQL command
set #x=${x}; is an SQL statement.
I thought that there may be an issue combining the two types as one statement as the MySQL --execute=statement, -e statement is supposed to execute the statement and quit.
The and quit part is why the redirected stdin is ignored when I tried my first idea:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x};" < script.sql
Solution
After further experiments, I figured out that simply appending a semi-colon to the source command will prevent the syntax error.
I can’t say why this works as a semi-colon isn’t usually required to terminate the last SQL statement of a list but there you have it:
mysql -h localhost -uuser -ppsw DB -e "set #x=${x}; source script.sql;"
As Glenn Jackman pointed out, if the shell variable is a non-numeric string, the shell variable will have to be wrapped in single quotes so that when the MySQL variable is being assigned, MySQL will treat the right hand side (the shell variable) as a string literal instead of as an identifier for a column name:
mysql -h localhost -uuser -ppsw DB -e "set #x='$x'; source script.sql;"
This version will also work safely with numeric strings as can be seen in the examples below. I’ve also removed the curly braces around the shell variable since they’re not necessary.
Examples
Contents of t.sql:
select now();
select #variable as 'Contents of variable';
Use a numeric string as the shell variable:
$ number=3
$ mysql -e "set #variable=$number; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:06:45 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| 3 |
+----------------------+
Use a non-numeric string as the shell variable generates errors:
$ text=text
$ mysql -e "set #variable=$text; source t.sql;"
ERROR 1054 (42S22) at line 1: Unknown column 'text' in 'field list'
$ text="This is a string"
$ mysql -e "set #variable=$text; source t.sql;"
ERROR 1064 (42000) at line 1: 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 'a string' at line 1
Now wrap the shell variable in single quotes:
$ mysql -e "set #variable='$text'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:08:04 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| This is a string |
+----------------------+
$ text=text
$ mysql -e "set #variable='$text'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:10:53 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| text |
+----------------------+
$ mysql -e "set #variable='$number'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:11:42 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| 3 |
+----------------------+
Using a non-existing shell variable will set the MySQL variable to an empty string:
$ mysql -e "set #variable='$nonexistent'; source t.sql;"
+---------------------+
| now() |
+---------------------+
| 2015-10-02 13:06:14 |
+---------------------+
+----------------------+
| Contents of variable |
+----------------------+
| |
+----------------------+
Related
I am simply trying to understand why these 2 commands have different outputs on my screen:
$> mysql -ularavel -ppassword -e 'select id from queue.jobs;'
+-------+
| id |
+-------+
| 20945 |
| 20946 |
+-------+
$> watch "mysql -ularavel -ppassword -e 'select id from queue.jobs;'"
Every 2.0s: mysql -ularavel -ppassword -e 'select id from queue.jobs;'
id
20945
20946
Notice that the watch command does not draw the table borders. I simplified this example, but for multiple columns the table is distorted and difficult to read.
So, why? Is there a difference between the input/output of the watch command that is different from what's directly in the terminal?
Tried on OSX with iTerm2 and the default Terminal app
I use a query command from bash which returns a number. However, it is printed as a table.
$ mysql -u muser -p$PASS mm -e "SELECT.....;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------------------+
| COUNT(DISTINCT ula.userid) |
+----------------------------+
| 29 |
+----------------------------+
I just want to get 29 and append that to a file with >> file.txt. How can I do that in mysql?
Use skip-column-names and batch-mode with -N and -B respectively:
mysql -u muser -p$PASS mm -NBe "SELECT.....;" >> file.txt
I am looking for a way to pull the information that is returned from Show Master Status so that I can assign the File and Position values to a variable.
I was able to set slave_relay_log_info and slave_work_info to tables but that does not show the local Master information I need.
SHOW MASTER STATUS;
I am not sure what table holds the Show Master Status data.
In Linux bash script you can try below command through mysql client to store the File and Position in variables
For File:
mysql -u username -p password -h IP -P Port -e "show master status" | grep "File"| cut -d ":" -f2
For Position:
mysql -u username -p password -h IP -P Port -e "show master status" | grep "Position"| cut -d ":" -f2
For MySQL 8.0 the log file and log position are in the log_status table of the performance_schema schema:
mysql> SELECT * FROM log_status ;
+--------------------------------------+------------------------------------------------------------------------------------------+------------------+-----------------------------------------------------------+
| SERVER_UUID | LOCAL | REPLICATION | STORAGE_ENGINES |
+--------------------------------------+------------------------------------------------------------------------------------------+------------------+-----------------------------------------------------------+
| 506c04ec-815c-11ed-a962-0800272d3b77 | {"gtid_executed": "", "binary_log_file": "mysql-bin.000022", "binary_log_position": 157} | {"channels": []} | {"InnoDB": {"LSN": 36558461, "LSN_checkpoint": 36558461}} |
+--------------------------------------+------------------------------------------------------------------------------------------+------------------+-----------------------------------------------------------+
The values can be extracted directly like this:
mysql> SELECT JSON_EXTRACT(`LOCAL`, '$.binary_log_file') AS file, JSON_EXTRACT(`LOCAL`, '$.binary_log_position') AS position FROM log_status ;
+--------------------+----------+
| file | position |
+--------------------+----------+
| "mysql-bin.000022" | 157 |
+--------------------+----------+
I am trying to create a bash shell script that runs an sql query and later on create a cronjob that runs it at an specific time.
I created my bash script see below
mysql -u $host -D $dbname -u $user -p$password -e $mySqlQuery
I have wrap -u -D -p -e all in variables. I have also change it to and executable file. When i run it. it gives out an output stating. Command not found. can anyone tell the mistake i made?
Below is the bash script
host="host"
user="user"
dbname="database"
password="password"
mySqlQuery = "SELECT *
FROM invoice i
JOIN item it
ON it.invoice_id = i.id
JOIN user u
ON i.user_id = u.id
JOIN gateway_response gr
ON gr.invoice_id = i.id
WHERE i.created_at >= '2019-03-01 00:00:00' and
i.created_at <= '2019-03-17 23:59:59' and i.status=9"
mysql -u $host -D $dbname -u $user -p$password -e $mySqlQuery
Below is the error i am receiving when i run it.
/home/chris2kus/givingDetectRun.sh: line 8: mySqlQuery: command not found /home/chris2kus/givingDetectRun.sh: line 20: mysql: command not found –
There must be no spaces around the = and the variable name mySqlQuery.
Also, I suggest you wrap your variables around double quotes, i.e., use "$host" instead of just $host.
You can write a file like this and chmod 755 filename.sh :
#!/bin/bash
host="localhost"
dbname="test"
user="root"
password="xxxxxxxxxx"
mySqlQuery="select *
from col;"
mysql -u $host -D $dbname -u $user -p$password -e "$mySqlQuery"
Sample
$chmod 755 testmysql.sh
$
$ ./testmysql.sh
+----+------+------+------+
| id | Col1 | Col2 | Col3 |
+----+------+------+------+
| 1 | 1 | 2 | 3 |
| 2 | 2 | 3 | 4 |
| 3 | 3 | 4 | 5 |
+----+------+------+------+
$
For starters, make sure your line 5 looks like
mySqlQuery="SELECT..."
(notice no spaces on either side of the assignment operator)
For seconds, try to re-format your entire MySQL query to fit into a single line.
(perhaps Heidi since it's a query, since that will keep you at least syntax-wise in the clear of errors)
For thirds, once you confirm that the bash runs as intended, add \n to tell the bash that you're continuing the command in the next row
Prototyping before optimization. Get it running before you get it flying.
How can i store mysql databases in linux using shell scripting
script:
mysql -uusername -hhostname -ppassword -e "show databases"
I think you want this: http://lists.mysql.com/mysql/96132
mysql> use mysql
Database changed
mysql> tee /tmp/mysqltee
Logging to file '/tmp/mysqltee'
mysql> show tables;
+-----------------+
| Tables_in_mysql |
+-----------------+
| columns_priv |
| db |
| host |
| tables_priv |
| user |
+-----------------+
5 rows in set (0.02 sec)
mysql> notee
Outfile disabled.
mysql>
If the file exist, the output will be appended to the existing file (/tmp/mysqltee).
As you can see, the output is also displayed on the screen. This may not be
what you want, especially if the output is big... You could use
mysql -e "select table_name from user_tables" database > output.txt
or
mysql database < script.sql > output.txt
from the os command line. (You may also need to use -u, -p and/or -h, use
the same as when you do a 'normal' start of the mysql client.)
it may help you
#!/bin/bash
results=($(mysql --user root -pwelcome -Bse "show databases;"))
The following code will retrieve all database names into a variable called dbnames. After that, it iterates will just echo a string with each name individually
#!/bin/bash
dbnames=`mysql --user=user --password=password -se "show databases;"`
for x in $dbnames;
do
echo "There is a database called $x"
done;