Using shell script to insert data into database [duplicate] - mysql

This question already has answers here:
Bash script to insert values in MySQL
(5 answers)
Closed 5 years ago.
Using shell script to insert data into database, but getting a blank value in the base
Im trying to make massive and randomly insert values from it.
#!/bin/bash
N=1
ARRAY=( adssa asdsa fdgfd vcbxcxv )
for el in "${ARRAY[#]}"
do echo $el
done | shuf | head -$N
mysql -u root -pPass somebase << EOF
INSERT INTO sometable (name) VALUES ('$el');
SELECT * FROM site_user;
EOF

Here's a simpler example that reproduces your problem:
for el in foo bar
do
echo "$el"
done | head -n 1
echo "This is blank: $el"
This happens because the for loop and your mysql statement are not connected in any way. You have to get the data from your loop/pipeline to mysql.
The simplest way of doing this might be a while read loop:
for el in foo bar
do
echo "$el"
done | head -n 1 | while read -r line
do
echo "This is not blank: $line"
done
In your example, this would be:
#!/bin/bash
N=1
ARRAY=( adssa asdsa fdgfd vcbxcxv )
for el in "${ARRAY[#]}"
do echo $el
done | shuf | head -$N | while read -r line
do
mysql -u root -pPass somebase << EOF
INSERT INTO sometable (name) VALUES ('$line');
SELECT * FROM site_user;
EOF
done
The simpler way would be:
#!/bin/bash
n=1
array=( adssa asdsa fdgfd vcbxcxv )
printf "INSERT INTO sometable (name) VALUES ('%s');\n" "${array[#]}" | \
shuf | head -n $n | mysql -u root -pPass somebase

Enclose your for loop using $(...) notation to get your output into the el variable.
#!/bin/bash
N=1
ARRAY=( adssa asdsa fdgfd vcbxcxv )
el=$(for el in "${ARRAY[#]}"
do echo $el
done | shuf | head -$N)
mysql -u root -p1550005 stat << EOF
INSERT INTO site_user (name) VALUES ('$el');
SELECT * FROM site_user;
EOF

Related

In ksh , pass parameters to mysql select query

I have a linux script that gets a variable and I store it to var JOB_EXEC_ID
I am trying to pass the value of this to a MySQL query
Here is MySQL query set-up
print "JOB EXEC ID value for DataMeer Job ${LOADJOB} is : ${JobExecId} " |
tee -a ${LOGDIR}/${LOGFILE}
#Log on to MySQL to get the DataId
#Remove first the output file that would house the dataid
rm -f ${SCRDIR}/list_dataid.csv
mysql -u root -pmonday1 ${DAPDBNAME} < ${SCRDIR}/dataid_query.nosql
SQLRTN=$?
if [[ ${SQLRTN} != 0 ]]
then
print "Return code from sqlcall - DAP : ${SQLRTN}" |
tee -a ${LOGDIR}/${LOGFILE}
print "Exiting $Script - 55 " |
tee -a ${LOGDIR}/${LOGFILE}
exit 55
fi
The file dataid_query.nosql looks like this:
set #job_exec_id=10151
select d.id DataId
from data d inner join dap_job_configuration djc on d.dap_job_configuration__id = djc.id
left outer join dap_job_execution dje on djc.id = dje.dap_job_configuration__id and dje.created_data__id = d.id
where dje.id=#job_exec_id
into OUTFILE "/home/app1ebb/cs/list_dataid.csv"
I want to pass the value of JOB_EXEC_ID to the set command that is currently hardcoded right now with a value of 10151
in place of
mysql -u root -pmonday1 ${DAPDBNAME} < ${SCRDIR}/dataid_query.nosql
SQLRTN=$?
this lines
sed "1 s/[0-9]*$/${JOB_EXEC_ID}/" > /tmp/dataid_query.nosql
mysql -u root -pmonday1 ${DAPDBNAME} < /tmp/dataid_query.nosql
SQLRTN=$?
rm /tmp/dataid_query.nosql

Bash mysql array do not get empty value

My Bash script makes an array from MySQL:
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT id,info1,info2 FROM table WHERE id=1")
info=($(for i in $info_tmp;do echo $i;done))
info1=${info[1]}
My problem is, that, if info1 is an empty string in the database, then $info1 became info2.
How can I put an empty string into $info array?
Mysql Database:
Id | info1 | info2
1 | | data2
2 | data3 | data4
$info_tmp
1 data2
2 data3 data4
Thank you for your answer
This is the final code that worked (#Barmar):
IFS="|"
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT CONCAT_WS('|', id,info1,info2) FROM table WHERE id=1")
info=(${info_tmp// / })
info1=${info[1]}
If there's a character that shouldn't appear in any of the columns, use that as a delimiter.
IFS="|"
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT CONCAT_WS('|', id,info1,info2) FROM table WHERE id=1")
This works because bash doesn't merge sequences of non-whitespace delimiters in IFS, only whitespace characters.
I'm not sure what the point of the for loop that copies $info_tmp to $info is, but you need to do the same thing there. If you use whitespace as your word delimiter, you'll never be able to get empty array values from command substitution.
What about temporarily adding a single character in your for-loop:
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT id,info1,info2 FROM table WHERE id=1")
info=($(for i in $info_tmp;do echo " "$i;done))
info1=$(${info[1]} | cut -c 2-)

If field exists then echo "something" in MySQL and BASH, else insert into table - Output to variable?

I'm attempting to write a little BASH script that will check for a number in a MySQL database, and if that number is already in the table to echo "AHHH THAT'S ALREADY THERE" and then if it's not in the database already to insert it into it..
mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface mylovelydb << EOF
SELECT * FROM mylittletable WHERE thenumber=$THENUMBER ;
EOF
mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface mylovelydb << EOF
INSERT INTO mylittletable VALUES ('$THENUMBER,'$THEDATE');
EOF
I guess a starting point would be to put the output of the MySQL query into a variable?
Actually, forget about testing the query results in Bash. You can do what you want (ie insert the data only when it doesn't exist) with just one SQL query :
INSERT INTO mylittletable(thenumber, thedate)
SELECT * FROM (SELECT '$THENUMBER', '$THEDATE') AS tmp
WHERE NOT EXISTS (
SELECT 1 FROM mylittletable WHERE thenumber = '$THENUMBER'
) LIMIT 1;
Even simpler : if your thenumber column is the primary key, or if you put a UNIQUE constraint on it, you can just use INSERT IGNORE (this will make the query silently fail when you try to insert the same number) :
INSERT IGNORE INTO mylittletable VALUES ('$THENUMBER','$THEDATE');
Personally, I would go with that second option. Consider creating a UNIQUE constraint if it makes sense for your data (or make thenumber a primary key if your table doesn't already have one) :
ALTER TABLE mylittletable ADD UNIQUE(thenumber);
EDIT :
If you want Bash to output something in case of a problem, just do an INSERT (without IGNORE) and use the exit status of the mysql client program :
echo "INSERT INTO mylittletable VALUES ($THENUMBER,'$THEDATE');" | mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface mylovelydb 2> /dev/null || echo Warning!
Or if you don't like long one-liners :
mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface mylovelydb 2> /dev/null << EOF
INSERT INTO mylittletable VALUES ($THENUMBER,'$THEDATE');
EOF
if [ $? -neq 0 ]
then
echo Warning!
fi
In case you're not familiar with it, the || operator is used like this in Bash :
# If command1 fails, run command2
command1 || command2
# Silly example
ls myfile 2> /dev/null || echo "No myfile here!"
Notice I also use an error redirection : 2> /dev/null so that errors are not output to the console.
You could try this one too.
#!/bin/bash
if read COUNT < <(mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface -E mylovelydb <<< "SELECT COUNT(*) AS __COUNT__ FROM mylittletable WHERE thenumber=$THENUMBER;" | sed -ne '/^__COUNT__/{ s/^.* //; p; }') && [[ COUNT -gt 0 ]]; then
echo "AHHH THAT'S ALREADY THERE"
else
mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface mylovelydb <<< "INSERT INTO mylittletable VALUES ('$THENUMBER,'$THEDATE');"
fi
You could aslo make them a little expanded with variables:
#!/bin/bash
SELECTCOMMAND="SELECT COUNT(*) AS __COUNT__ FROM mylittletable WHERE thenumber=$THENUMBER;"
INSERTCOMMAND="INSERT INTO mylittletable VALUES ('$THENUMBER,'$THEDATE');"
if read COUNT < <(mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface -E mylovelydb <<< "$SELECTCOMMAND" | sed -ne '/^__COUNT__/{ s/^.* //; p; }') && [[ COUNT -gt 0 ]]; then
echo "AHHH THAT'S ALREADY THERE"
else
mysql --host=192.168.0.0 --user=garfunkle --password=spatulaface mylovelydb <<< "$INSERTCOMMAND"
fi

bash - SQL Query Outputs to variable

Im new in bash scripting.
I want to save sql-query outputs in variable, but
actually I must connect for every query to mysql with:
mysql -u $MYUSER -p$MYPASS -D database
and want to save every output in seperatly variable
sample query is: SELECT domain FROM domains WHERE user='$USER'
to
$variable1 = FIRST_OUTPUT
$variable2 = 2ND_OUTPUT
thank you
Taken from bash script - select from database into variable, you can read the query result into a variable.
Example
mysql> SELECT * FROM domains;
+-------+---------+
| user | domain |
+-------+---------+
| user1 | domain1 |
| user2 | domain2 |
| user3 | domain3 |
+-------+---------+
Usage
$ myvar=$(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
$ echo $myvar
domain1 domain2 domain3
echo is the bash command for output. You can then split $myvar into separate variables:
$ read var1 var2 var3 <<< $myvar
$ echo $var1
domain1
$ echo $var2
domain2
You can combine these two commands into a single one:
read var1 var2 var3 <<< $(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
It is possible to store the results into arrays (useful if you don't know how many records there):
$ read -ra vars <<< $(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
$ for i in "${vars[#]}"; do
$ echo $i
$ done
domain1
domain2
domain3
Another way of doing is:
dbquery=`mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains"`
dbquery_array=( $( for i in $dbquery ; do echo $i ; done ) )
The first line stores all the output from the query in a varriable dbquery in a array-like-way. The second line converts the dbquery into an array dbquery_array with a simple for loop.
I did this
variable=mysql -u root -ppassworrd database << EOF
select MAX(variable) AS a from table where variable2 = 'SOMETEXT' AND day(datevalue) >= 22;
EOF
I hope it helps

Easiest way to get count val from mysql in bash

Maybe i should use python or perl but i dont know any.
I have 4 statements and i would like to check if there are any errors longer then an hour. My user is setup so i dont need to enter a mysql user/pass. This statement is in mysql_webapp_error_check.sh
#!/bin/bash
mysql testdb -e "select count(*) from tbl where last_error_date < DATE_SUB(NOW(), INTERVAL 1 HOUR);"
How do i make it give me the return value (count(*)) instead of printing to screen?
Then i'll write an if statement and output to stdout/err for cron to use to email me (otherwise i want the script to be silent so nothing is emailed unless theres a problem)
Searched the same, -s for silent works exactly for me.
#!/bin/bash
result=`mysql testdb -s -e "select count(*) from tbl where last_error_date < DATE_SUB(NOW(), INTERVAL 1 HOUR);"`
echo result = .$result.
PS.: There is also a --batch parameter in my mysql Ver 14.14 Distrib 5.1.49 which "Write fields without conversion. Used with --batch" so its a little off-topic here, but should be mentioned here.
in bash, you use $() syntax.
#!/bin/bash
ret=$(mysql testdb -e "select count(*) from tbl where last_error_date < DATE_SUB(NOW(), INTERVAL 1 HOUR);")
if [[ "$ret" > 0 ]];then
echo "there is count"
else
echo "no count"
fi
I usually do this:
var=`mysql -e "SELECT COUNT(*) FROM ...\G" | awk '/COUNT/{print $2}/'`
For my part I simply use grep -v to exclude the line printing count(*) from the return of MySQL.
So I get the counter like that:
db_name="NAME_DB";
db_user="USER_DB";
db_pwd="PWD_DB";
counter=`mysql -u${db_user} -p${db_pwd} ${db_name} -e "SELECT count(*) FROM my_table WHERE something = '1';" | grep -v "count"`;
echo "Count for request: $counter";
I use it for some Wordpress stuff this way, reading databases infos from the wp-config.php file:
wp_db_infos="wp-config.php";
wp_db=`cat ${wp_db_infos} | grep "DB_NAME" | awk -F ', ' '{print $2}' | awk -F "'" '{print $2}'`;
wp_user=`cat ${wp_db_infos} | grep "DB_USER" | awk -F ', ' '{print $2}' | awk -F "'" '{print $2}'`;
wp_pwd=`cat ${wp_db_infos} | grep "DB_PASSWORD" | awk -F ', ' '{print $2}' | awk -F "'" '{print $2}'`;
img_to_update=`mysql -u${wp_user} -p${wp_pwd} ${wp_db} -e "SELECT count(*) FROM wp_offres WHERE maj_img = '1';" | grep -v "count"`;
#!/bin/bash
echo show databases\; | mysql -u root | (while read x; do
echo "$x"
y="$x"
done
echo "$y"
)
local count=$(mysql -u root --disable-column-names --batch --execute "SELECT COUNT(*) FROM mysql.user WHERE user = '$DstDbName'")
if [[ "$count" > 0 ]]
then
fi
--batch - do clear output w/o borders
--disable-column-names - prints only row with value
no creasy AWK used :)