I have a query that I need to loop.
query="select '$dbserver' as server;"
while read dbserver username password dbname type
do
mysql -h$dbserver -u$username -p$password $dbname -Be"$query" >> /home/develop/myreport.csv
done < $dblist
The following line expands correctly.
mysql -h$dbserver -u$username -p$password $dbname -Be"select '$dbserver' as server;" >> /home/develop/myreport.csv
But when I take out the query and save it in a variable as shown above, it stops working as expected and gives blank value for "dbserver". The line mentioned in the loop above does not work. How to correct this problem?
Put the query assignment inside the loop. Before the loop your variables are not defined yet (i.e. blank)
If you want the
'$dbserver'
in the query expanded inside the loop, you'd probably write:As originally written, the query string is evaluated before any value is assigned to
$dbserver
, which is why you got the empty string in the output.Note that the output redirection was done just once - on the
done
line rather than each time in the loop (which means that you don't need append any more).Getting the query created outside the loop is normally something you can do, using
eval
. However, because the value of the$dbserver
is enclosed inside single quotes, this turns out to be hard. If the DBMS you are using permits the use of double quotes around strings (contrary to the SQL standard), then this works with an eval:You can then adapt this to use single quotes by replacing the '
"
' with the ''\''
' sequence:That is, however, the sort of quote sequence that sends sane people from the room screaming - excuse me a moment while I vacate the premises noisily! [...later...] That's better!
Explanation:
'\''
.The
eval
process runs an extra lot of expansion on the string. The backslash-quote pairs are replaced by just quote; the current value of$dbserver
is inserted. This can then be passed to the command as an ordinary argument.The difficulty with
eval
is ensuring that you don't get unexpected side-effects. This is doubly complex with MySQL which uses back-quotes to enclose keywords used as tokens. That notation interacts diabolically witheval
, of course. However, with single quotes around the whole query and backslash-backquote in place of each backquote, you can do it:I don't think it can be recommended, though.