I have a batch file that extracts one row from a database and uses that data as a variable to use the value to be a filename, and exports data as text file.
It works fine except for exporting two text files.
One of the two files is the correct file.
The other one is the unnecessary file. The filename is ".txt" and has the same data as the first one.
Here is my bat file:
SET SQLCMD=sqlcmd -S server -d db -Q "set NOCOUNT
on; select name from t1" -h-1
FOR /F "usebackq delims=, tokens=1" %%i IN (`%SQLCMD%`) DO (
CALL :PROCESSING %%i
)
:PROCESSING
SET COL1=%1
bcp "SELECT * FROM t1" queryout "C:\Export\%COL1%.txt." -S server -T -c
What do I need to fix to get only one file?
Since I am new to coding, if anyone could help, that would be very appreciated.
Thank you,
Related
I have multiple .sql script files and want to execute them one by one in batch file with proper logging mechanism.
I wrote below batch command to solve the problem
#ECHO OFF
SET SQLCMD="C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\SQLCMD.EXE"
SET PATH="C:\Users\sql_scripts\"
SET SERVER="server_name"
SET DB="database"
SET LOGIN="user_name"
SET PASSWORD="password"
SET OUTPUT="C:\Users\sql_scripts\output\OutputLog.txt"
CD %PATH%
ECHO %date% %time% > %OUTPUT%
for %%f in (*.sql) do (
%SQLCMD% -S %SERVER% -d %DB% -U %LOGIN% -P %PASSWORD% -i %%~f -b >> %OUTPUT%
)
But it has few problems that I want to solve as listed below :
I want to create dynamic out put file names based on input file name. Example if input sql file
name is "test.sql" then I want to create output file in "output" folder with name "test.sql".
Currently It writes all the log to one file i.e. OutputLog.txt
I want to show output log with script of execution to identify which script produced what
output. Let's say in one script file 5 scripts present then in output file I want to show the
script and its output log.
Currently, the following code in a batch file works: it runs all SQL scripts in %SCRIPTFOLDER% and sends each script's output to a CSV within the same folder as the scripts.
FOR /F "tokens=*" %%S IN (
'DIR /B "%SCRIPTFOLDER%\*.sql" '
) DO (
sqlcmd -b -S %INSTANCE% -d %DATABASE% -i "%%~fS" -s "|" -o "%%~dpnS.csv" -W
IF ERRORLEVEL 1 GOTO errorhandling
ECHO %%~nS.csv successfully created
)
What I'd like to do is allow the user to specify where the generated CSVs get sent to using a variable %OUTPUTFOLDER%.
I tried placing %OUTPUTFOLDER%, which is a full path, drive, and folders (e.g. D:\some folder\output) in various positions within %%~dpnS.csv. Specifically,
%%~dp%OUTPUTFOLDER%nS.csv
and
%%~dpn%OUTPUTFOLDER%S.csv
but they didn't work and I'm (probably obviously to you) woefully inept at batch file syntax!
I understand that dp is the drive and path and that S is the file name, but I'm not sure how to integrate that with a the variable that is the path.
The iterating variable is %%S, the modifier ~dpn forces an evaluation of drive path and name.
In this case you want to specify the drive and path yourself so depending on wether %OUTPUTFOLDER% has a trailing backslash
-o "%OUTPUTFOLDER%%%~nS"
or not use:
-o "%OUTPUTFOLDER%\%%~nS"
I have a complicated batch script involving multiple BCP commands that load SQL server with flat file data. I am using a branch statement that logs the result of the command into a log file. This is all working fine.
The result is also logged in an SQL table as a success or failure. What I am trying to do is, upon failure, insert the contents of the log file into the SQL log table using what I thought was a simple redirect. It isn't working.
Here is what I am doing in a batch file in a Win Server 2012 environment:
BCP (the parameters here don't matter) >> %LogFile% (
MOVE %FileName% to Archive/%FileName%
sqlcmd -E -Q "EXEC spImportLog 'SUCCESS', %FileName%, ''
) || (
SET /p LogText=<%LogFile%
sqlcmd -E -Q "EXEC spImportLog 'FAILED', %FileName%, %LogText%
)
This code executes without error. The true part of the statement works fine.
The false part executes fine but I end up with empty string instead of
the contents of %LogText%.
When I run this from a command prompt, the SET looks like this:
SET /p LogText<0Log_2016_9_23.log
The %LogFile% is a variable because it is dynamically named at run time based on today's date. I don't know where the 0 after the less than sign is coming from, or if it is the source of my problem. Any ideas?
YADXP.
SET /p LogText=<%LogFile%
setlocal enabledelayedexpansion
sqlcmd -E -Q "EXEC spImportLog 'FAILED', %FileName%, !LogText!
endlocal
should work. See the billion or so SO entries about "delayed expansion"
As I said, set /p var=<filename will set the variable from the first line of the file. Since the file accumulates values and is initially sset to contain just one line (AAUI) 'None' then that is the value that will be read from the file.
Try
for /f "usebackqdelims=" %%a in ("%LogFile%") do set "logtext=%%a"
setlocal enabledelayedexpansion
sqlcmd -E -Q "EXEC spImportLog 'FAILED', %FileName%, !LogText!
endlocal
which should read every line of %logfile% and assign to logtest the value (of each line) in turn, so that when the for terminates, logtext will have the value of the last line of the file.
Okay, thanks for the posts. It doesn't sound like what I want to do is possible. At least not the way I am trying to do it. What I wanted is to store the entire contents of %LogFile% in a variable as a textstream, and then insert that text stream into a varchar column in SQL server. In retrospect, I wasn't clear enough in my initial post exactly the problem I was trying to solve. I know I can store the command results (multiple lines) in a temporary table in SQL Server. It is just that it requires using xp_cmdshell, which I was hoping to avoid.
Can we pass values of scripting variables to environment variables when we are witing codes in sqlcmd scripts or batch scripts and vice versa ?
Using batch variables in sqlcmd
a) Directly placing them in the command line. The cmd parser will expand the variables to the value as it is written in the line
set "lastName=Smith"
sqlcmd -Q "SELECT * From myTable Where LastName='%lastName%'"
b) Using declared variables in the sql query, and using the previous method to declare them in the sqlcmd command. If we have a query.sql filename containing
SELECT * From myTable Where LastName='$(LastName)'
Then it is possible to do the following call
set "lastName=Smith"
sqlcmd -i query.sql -v LastName="%lastName%"
Using output of sqlcmd in batch files
a) Send the output to a file (-o switch in sqlcmd) and then process it. See for /?
sqlcmd -i query.sql -o data.txt -h -1
for /f "tokens=*" %%a in (data.txt) do ....
b) Directly process the output of the command. Again with for /f command.
for /f "tokens=*" %%a in ('sqlcmd -i query.sql -h -1') do ....
In both cases, if what is needed is to assign value to a batch variable, you will have something like
for /f "... options ..." %%a in ('sqlcmd -i query.sql -h -1') do (
....
set "varname=%%a"
....
)
processing the output/file and assigning the data to the variables.
I'm in a process of creating a batch file to list names of all SQL scripts in a folder to a text file. My plan to convert this text file to a batch file so that I can use it to execute the scripts in the server. So I would like to have the following string appended before each file name while creating the initial text file
sqlcmd -S %MSSQLSERVER_NAME% -d %MSSQLSERVER_DBNAME% -i
This is a batch file command and I would like to be appended before the each file names.
eg:
sqlcmd -S %MSSQLSERVER_NAME% -d %MSSQLSERVER_DBNAME% -i 001_ALTER_PERSON.sql
The code I'm using is
set MSSQLSERVER_NAME = "%MSSQLSERVER_NAME%"
set %MSSQLSERVER_DBNAME = "%MSSQLSERVER_DBNAME%"
set myvar=sqlcmd -S %MSSQLSERVER_NAME% -d %MSSQLSERVER_DBNAME% -i
for /r . %%g in (*.sql) do echo %myvar% %%~nxg >> D:\test.txt
pause
Out put I'm getting
sqlcmd -S -d -i 015_ALTER_vBOARD_PAPERS.sql
Let me know how to tackle this
set myvar=sqlcmd -S %%MSSQLSERVER_NAME%% -d %%MSSQLSERVER_DBNAME%% -i
should cure your problem - % escapes %
note that spaces ARE significant in variable names, so set var = somethingwill set var[space] to [space]something
set %varname%=... is rare -it sets the variablename (contents of varname).
Even more rare to have unbalanced %... not sure that will work at all...