BATCH FILE : not able to display variable value by accessing by %variable% - batch-file

I am using widows XP OS and have batch file where I set few variable values.
when i echo those varibales i can see the values, but when i use it in some commands i get empty sting as its value.
Sample Batch file
#ECHO OFF
SET "output=select * from employee where empid='160'"
CALL SET output=%%output:'=''%%
ECHO "%output%"
sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q "%output%' " -d tesdb
o/p select * from employee where empid=''160''
and value of variable in sqlcmd command is empty space.

I'm not sure, what you want to do.
#ECHO OFF
SET output=select * from employee where empid="160"
ECHO %output%
ECHO sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q '%output%' -d tesdb
..output is:
select * from employee where empid="160"
sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q 'select * from employee where empid="160"' -d tesdb

Try to place the quotes as follows:
SET output="select * from employee where empid='160'"
sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q %output% -d tesdb

Related

Is it possible to have a persistent psql connection in bash?

I have a very large bash script and I make thousands of psql queries throughout it which I suspect is slowing it down. I have created this MWE which proves my theory. I am assuming this slow down is because of having to connect to the db repeatedly. Is there a way to remain connected to psql in bash?
#!/bin/bash
DB_NAME=testdb
DB_USER=user1 #UPDATE THIS
#DROP DB
SQL_QUERY="DROP DATABASE IF EXISTS $DB_NAME;"
echo $SQL_QUERY | sudo -u $DB_USER psql >/dev/null
#CREATE DB
SQL_QUERY="CREATE DATABASE $DB_NAME;"
echo $SQL_QUERY | sudo -u $DB_USER psql >/dev/null
#CREATE TABLE
SQL_QUERY="CREATE TABLE foo
(
id BIGSERIAL PRIMARY KEY,
problems INTEGER
);"
echo $SQL_QUERY | sudo -u $DB_USER psql -d $DB_NAME >/dev/null
TARGET_ITERATIONS=1000
#MULTIPLE DB CALLS
SQL_QUERY="INSERT INTO foo
(
problems
)
VALUES
(
99
);"
START_TIME=$(date +%s)
for ITERATION in $(seq $TARGET_ITERATIONS)
do
echo $SQL_QUERY | sudo -u $DB_USER psql -d $DB_NAME >/dev/null
done
STOP_TIME=$(date +%s)
echo "Multiple Call Duration (s): $((STOP_TIME-START_TIME))"
#Single db call
SQL_QUERY=""
for ITERATION in $(seq $TARGET_ITERATIONS)
do
SQL_QUERY+="INSERT INTO foo
(
problems
)
VALUES
(
99
);"
done
START_TIME=$(date +%s)
echo $SQL_QUERY | sudo -u postgres psql -d $DB_NAME >/dev/null
STOP_TIME=$(date +%s)
echo "Single Call Duration (s): $((STOP_TIME-START_TIME))"
Output:
$ ./test_psql.sh
Multiple Call Duration (s): 64
Single Call Duration (s): 12
Per your comment, try running this:
#/bin/bash
mkfifo /tmp/mypipe
chmod a+r /tmp/mypipe
sleep 10000 > /tmp/mypipe &
psql -f /tmp/mypipe &
echo "\pset pager off" > /tmp/mypipe
echo "select count(*) from information_schema.columns;" > /tmp/mypipe
echo "select count(*) from information_schema.columns;" > /tmp/mypipe
sleep 3
echo "select count(*) from information_schema.columns;" > /tmp/mypipe
echo "\q" > /tmp/mypipe
rm /tmp/mypipe

Whitespace differences with output

I have written a script to generate a .CSV file from an SQLCMD query, but when I open it in Notepad, there is unwanted spacing between data. When I manually paste the query results in the .csv file then there is no spacing when I open it in Notepad.
Please do let me know, what should I do to avoid the issue.
My minimal script example:
set destfolder="c:\Test"
SQLCMD -s "--Database name--" -d Audit -E -I -i "C:\Test\Mandates.sql" -s "," -o "c:\Test\tempfile.csv"
findstr /v /c:"---" "c:\Test\tempfile.csv" > "%destfolder%\%filename%"
del "%destfolder%\tempfile.csv"
Issue:
CustomerName,CustomerNumber,Value
Adam, 123456789, 0
Expected:
CustomerName,CustomerNumber,Value
Adam,123456789,0
I got the solution.
SQLCMD -s "--Database name--" -d Audit -E -I -W -i "C:\Test\Mandates.sql" -s "," -o "c:\Test\tempfile.csv"
I have used -W in the above script which resolves the issue. Thanks

Using sqlcmd in a batch script to run multiple scripts with output files

I need to run about 50 scripts in a folder using sqlcmd from a batch file. Each script's query results need to be sent to its own output file. I have a working batch file that just runs each from a separate line:
sqlcmd -S %INSTANCE% -d %DATABASE% -U %USERNAME% -P "%PASSWORD%" -i "%SCRIPTFOLDER%\master_departments.sql" -s "|" -o "%OUTPUTFOLDER%\master_departments.csv" -W
sqlcmd -S %INSTANCE% -d %DATABASE% -U %USERNAME% -P "%PASSWORD%" -i "%SCRIPTFOLDER%\master_companies.sql" -s "|" -o "%OUTPUTFOLDER%\master_companies.csv" -W
sqlcmd -S %INSTANCE% -d %DATABASE% -U %USERNAME% -P %PASSWORD% -i "%SCRIPTFOLDER%\bill_history.sql" -s "|" -o "%OUTPUTFOLDER%\bill_history.csv" -W
sqlcmd -S %INSTANCE% -d %DATABASE% -U %USERNAME% -P %PASSWORD% -i "%SCRIPTFOLDER%\episodes.sql" -s "|" -o "%OUTPUTFOLDER%\episodes.csv" -W
Is there any way to run this in some kind of loop? I've seen examples that run a loop of all SQL scripts in a folder, but nothing that I've seen does it with an output file set.
Per #LotPings' suggestion I used the below code:
set INSTANCE=<someinstance>
set DATABASE=<somedb>
set USERNAME=<someuser>
set PASSWORD=<somepassword>
set "SCRIPTFOLDER=D:\<pathToScripts>\"
set "OUTPUTFOLDER=D:\<pathForOutput>\"
#Echo off
For /F "tokens=*" %%S in ('Dir /B "%SCRIPTFOLDER%*.sql" '
) do echo sqlcmd -S %INSTANCE% -d %DATABASE% -U %USERNAME% -P "%PASSWORD%" -i "%%~fS" -s "|" -o "%%~dpnS.csv" -W
#pause
I ran that in a batch file and when it paused, the last line said, "The system cannot find the file specified."
Thinking it was perhaps the backslashes in my paths, I removed them and put a slash before the .sql in the for line, but I got the same results.
Removing the backslash altogether resulted in a "File not found" message when I ran it like that.
In case your output file name matches the script name (without extension)
and your parameters are the same for all scripts
#Echo off
For /F "tokens=*" %%S in ('Dir /B "%SCRIPTFOLDER%*.sql" '
) do echo sqlcmd -S %INSTANCE% -d %DATABASE% -U %USERNAME% -P "%PASSWORD%" -i "%%~fS" -s "|" -o "%%~dpnS.csv" -W
The echo in front of sqlcmd prevents execution and allows to review the output. If all looks OK, remove the echo.
The for variable behaviour can be changed with ~ modifiers, see For /? or visit ss64.com/nt/for.html / syntax-args
To pass a folder to the batch you can input via set /P or hand over via command line arguments.

How to use a shrinkDBs.bat file to truncate all log.ldf files in nested folders?

I would like to be able to shrink all log files in nested folders. I have used this same script to modify databases but I am having problems with the shrink command.
When I run this script, I get an error stating it can not find the database in the sys.database_files. So I'm guessing my database is going by a different name in sys.database_files or simply is not added. Can you help?
for /r /d %%i in (*) do (
ECHO %%i\MY_DB.mdf
osql -S LOCALHOST\SQLEXPRESS -U johan -P johan_j-d master -Q "EXEC sp_attach_db 'MY_DB', '%%i\MY_DB.mdf', '%%i\MY_DB_log.ldf';"
osql -S LOCALHOST\SQLEXPRESS -U johan -P johan_j -d MY_DB -Q "DBCC SHRINKFILE (N'MY_DB_log',0,TRUNCATEONLY);"
osql -S LOCALHOST\SQLEXPRESS -U johan -P johan_j -d master -Q "EXEC sp_detach_db 'MY_DB';"
)
Problem solved. I should have been using the logical file name not the physical file name.

How can I skip one file in a filesets?

Below is my code in batchfile:
for %%f in (%~dp0*.sql) do (
sqlcmd -S %SName% -U %UName% -P %Pwd% -d %DbName% -I -i "%%f" >>TsDeploy.txt 2>&1
)
the question is there is one file in that set must be NOT Run as first one.(cause the others is script file about create Table,that one is to insert data into table ).
How Should I do to achieve the goal in ONLY ONE batchfile?
You could rename the sql file that must not run first so that it sorts to the end (prefix with z?).
Or you could do something like
for %%f in (%~dp0*.sql) do (
if "%~nxf" neq "fileNameNotToRunFirst.sql" (
sqlcmd -S %SName% -U %UName% -P %Pwd% -d %DbName% -I -i "%%f" >>TsDeploy.txt 2>&1
)
)
sqlcmd -S %SName% -U %UName% -P %Pwd% -d %DbName% -I -i "%~dp0fileNameNotToRunFirst.sql" >>TsDeploy.txt 2>&1
Or you could create a master sql script that calls each of the others in the proper order, as described in How to Run a Series of T-SQL Scripts in a Specific Order

Resources