To put output of a query executed using SQLCMD into a variable which can be used in Batch script - sqlcmd

I want the output of an SQL query Select count(*) from Table to be used as a variable in a Batch script. I am using sqlcmd to execute this query, but haven't figured out how to do this properly.
Any help or examples would be appreciated.

Here is solution I used to get output from query in a batch script variable. This is used in a windows .cmd batch script file. Basically it outputs to a temp file and then extracts the text into a variable.
sqlcmd.exe <SERVER & DB OPTIONS> -h-1 -Q "SET NOCOUNT ON; SELECT COUNT(*) FROM Table" -o output.txt
set /P recCount= < output.txt
echo %recCount%
del output.txt
Notice the use of the -h-1 flag (which tells SQLCMD to suppress column headings in the output) and NOCOUNT within in the SQL command (to suppress the count of rows affected). Also if the query was being made for a string you may want to use the -W parameter to remove trailing spaces from the output.

Assuming that you're talking about Microsoft's SQLCMD on Windows (and your Bash is therefore a cygwin or msys or such-like)
VAR=`sqlcmd.exe <SERVER & DB OPTIONS> -r1 -h-1 -Q "SET NOCOUNT ON; SELECT COUNT(*) FROM Table"`
should do it nicely for you.

You can do this in Bash Script
SQLCMD="sqlcmd -h -1 -S $SERVERNAME -U $USERNAME -P $PASSWORD -d $DBNAME -Q"
var=$($SQLCMD " SET NOCOUNT ON; SELECT COUNT(*) FROM TableName ")
echo "Value: $var"

Try this:
DECLARE #abr int
SELECT #abr = COUNT(*) FROM mytable
:setvar abr (#abr)
print $(abr)

Related

In bash script how to use cli argument as a variable for mysql query and capture result?

With this SQL query film_name is to be set with value of $1 coming from command line argument. And of course I want to capture the result any ideas? I want to do something like this
result=$(mysql myapp -B --column-names=0 -e "select film_id from films where film_name='$1'")
But this does not work. I think bash has a problem with variables in the SQL body
Maybe you can try something like the below, using "set" :
myarg=$1
mysql -h<host> -u<user> -p<password> <<"SQL"
set #my_arg='$myarg';
select film_id from films where film_name=#my_arg;
SQL

Using batch variable in sqlcmd query

I'm trying to create a batch to execute a few sql script and some queries. I use sqlcmd in my batch like this :
#echo off
sqlcmd -S server -U user -P password -Q query
As I will execute different queries on the same server, I'd like to replace the server statement with a variable. So I could write something like this :
#echo off
SET server=192.X.X.X
sqlcmd -S server -U user -P password -Q first query
sqlcmd -S server -U user -P password -Q second query
I found this question on SO but I'm still unable to understand how that works :
SQLCMD using batch variable in query
Does anyone have an idea ?
Thanks a lot!
Expanding on my comment a little:
#Echo off
Set "server=192.X.X.X"
Set "user=myname"
Set "password=pa55w0rd"
sqlcmd -S %server% -U %user% -P %password% -Q first query
sqlcmd -S %server% -U %user% -P %password% -Q second query
You may wish to enclose your variables with relevant quoting as necessary.
From Microsoft: "Cmd.exe provides the batch parameter expansion variables %0 through %9. When you use batch parameters in a batch file, %0 is replaced by the batch file name, and %1 through %9 are replaced by the corresponding arguments that you type at the command line."
So if the number of queries you wish to execute is known just pass them in through parameters like this:
Test.bat:
#echo off
SET server=192.X.X.X
sqlcmd -S server -U user -P password -Q %1%
sqlcmd -S server -U user -P password -Q %2%
Then call Test.bat like this:
Test.bat "Select * from Test1" "Select * From Test2"
You can pass up to 9 queries this way.

MySql: dump BLOB into local file

how do i dump the contents of a blob to a file? the thing is that the resulting file should be stored on a client and not on the server, and the solution should be handled in a shell script.
SELECT ... INTO OUTFILE/DUMPFILE ...
will fail because this would save the file directly on the server, not on the client.
echo "USE my_db; SELECT my_blob FROM my_table LIMIT 1" | mysql --<connection params> > $OUTFILE
writes garbled data into the local $OUTFILE, i guess including some formatting.
is there a way to disbale all formatting, or how can i get a 1:1 dump to a file?
any help is greatly appreciated!
You can accomplish this with the MySQL client as long as you use the proper options.
In particular you should use double-silent mode to suppress table formatting and the column name, and use raw mode so no characters are escaped.
Here's an update of the command you tried that should get you on the right track:
mysql --<connection params> \
my_db \
--raw \
--silent \
--silent \
--execute \
"SELECT my_blob FROM my_table LIMIT 1" > $OUTFILE
I had to extract all files out of a table and came up with a simple bash script based on previous answer.
It's not very smart, but it does the job :)
#!/bin/bash
myUser=user
myPass=secret
myHost=localhost
myDb=database
myCmd="mysql -u$myUser -p$myPass -h$myHost -D$myDb"
$myCmd -e "SELECT id, file_name FROM files;" |
while read id file_name; do
echo $id $file_name;
$myCmd --raw --silent --silent -e "SELECT file_data FROM files WHERE id=$id LIMIT 1;" > "$file_name"
done;

Bash: How to invoke command and store the result in a variable?

Basically I want to be able to invoke a given command, in this case mysql -uanon -ppwd -db mydb -e "select count(*) from table1". And then take this commands result (the count on that table) and place it in a variable in bash script. What is the simplest way to achieve this?
You most likely want to use batch mode (-B) and disable column names (--disable-column-names) for non-interactive mysql output:
out=$(mysql -B -db mydb -uanon -ppwd --disable-column-names -e "select count(*) from table1";)
$ A=$(mysql -uanon -ppwd -db mydb -e "select count(*) from table1")
$ echo $A
In other words, use the $() syntax.

MySQL - mysqldump --routines to only export 1 stored procedure (by name) and not every routine

So we have a lot of routines that come out from exporting. We often need to get these out in CLI, make changes, and bring them back in. Yes, some of these are managed by different folks and a better change control is required, but for now this is the situation.
If I do:
mysqldump --routines --no-create-info --no-data --no-create-db
then great, I have 200 functions. I need to go through a file to find just the one or set I want.
Is there anyway to mysqldump routines that I want like there is for tables?
Another way to go about this would be the following. Do note, however, that you have to have root privileges in the target database in order to import rows into mysql.proc:
mysqldump --compact --no-create-info --where="db='yourdatabasename' AND type='PROCEDURE' AND name IN ('yoursp1', 'yoursp2')" --databases mysql --tables proc
To answer your exact question: no.
But this will probably give you what you want.
Take a look at SHOW CREATE PROCEDURE and SHOW CREATE FUNCTION:
http://dev.mysql.com/doc/refman/5.0/en/show-create-procedure.html
http://dev.mysql.com/doc/refman/5.0/en/show-create-function.html
Those commands allow you to dump the code for one routine at a time.
It is possible to dump a single function or procedure using the command that Ike Walker mentioned, but the SHOW CREATE PROCEDURE and SHOW CREATE FUNCTION commands don't allow to select only a few columns from the output.
Here is a example of a Windows batch command line to dump a single procedure, using the system table mysql.proc:
mysql --defaults-extra-file=myconfig.cnf --skip-column-names --raw --batch mydatabase -e "SELECT CONCAT('DELIMITER $$\nCREATE PROCEDURE `', specific_name, '`(', param_list, ') AS \n', body_utf8, ' $$\nDELIMITER ;\n') AS `stmt` FROM `mysql`.`proc` WHERE `db` = 'mydatabase' AND specific_name = 'myprocedure';" 1> myprocedure.sql
This will redirect the output of mysql into the file myprocedure.sql.
The --batch option tells the mysql client to remove the table borders from the output.
The --skip-column-names option removes the column headers from the output.
The --raw option tells MySQL to not escape special characters on the output, keeping new lines as is instead of replacing them with \n.
And if you want to dump ALL the procedures in different files, this example in batch should work:
dump-procedures.bat
#echo off
REM set the target database
set database=mydatabase
REM set the connection configuration file
set auth=--defaults-extra-file=myconfig.cnf
REM set the routine type you want to dump
set routine_type=PROCEDURE
set list_file=%routine_type%S.csv
if "%routine_type%"=="PROCEDURE" (
set ending=AS
)
if "%routine_type%"=="FUNCTION" (
set ending=RETURNS ', `returns`, '
)
echo Dumping %routine_type% list to %list_file%
mysql %auth% --skip-column-names --raw %database% -e "SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_TYPE = '%routine_type%';" 1> %list_file%
for /f "tokens=*" %%a in (%list_file%) do (
echo Dumping %routine_type% %%a
mysql %auth% --skip-column-names --raw --batch %database% -e "SELECT CONCAT('DELIMITER $$\nCREATE PROCEDURE `', specific_name, '`(', param_list, ') %ending% \n', body_utf8, ' $$\nDELIMITER ;\n') AS `stmt` FROM `mysql`.`proc` WHERE `db` = '%database%' AND specific_name = '%%a';" 1> %%a.sql
)
It works in 2 steps, where it first dumps the list of all procedures into the file procedures.csv, and then iterates in each line and uses the names of the procedures to dump each procedure in a different file.
In this example, I am also using the option --defaults-extra-file, where some configuration parameters are set in a different file, and allows to invoke the command without needing to type the password each time or writing the password inside the batch itself. I created a file with this content
myconfig.cnf
[client]
host=localhost
port=3306
user=myusername
password=mypassword
This solution also works with function, defining the routine_type variable to:
set routine_type=FUNCTION
I have written the solution within bash.
For one procedure
mysql -NB -u root my_database -e 'show create procedure `myProcedure`' |\
xargs -n 1 -d '\t' echo |\
egrep '^CREATE' |\
xargs --null echo -e >
For all procedures
mysql -NB -u root -e 'SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = "my_database" AND ROUTINE_TYPE = "PROCEDURE"' |\
xargs -n 1 -I {} mysql -NB -u root my_database -e 'show create procedure `{}`' |\
xargs -n 1 -d '\t' echo |\
egrep '^CREATE' |\
xargs --null echo -e
This is trick,
create DATABASE to local.
dump your DATABASE include your STORE PROCEDURE to local.
or
just use mysql*yog and copy database, check STORE PROCEDURE (example: 1 store procedure) to local server.
dump your DATABASE local . yeah, you have 1 store procedure in your dump. remember use --routine if u want sp/events only.
trick is fun, isn't lazy, just tricked.