Pass parameter in create table using batch file and SQLCMD - sql

I have to pass a parameter (date) into a create table script that will be triggered via a batch file. I have used SQLCMD and the code is as follows
Batch
for /f "tokens=1-4 delims=/:." %%a in ("%TIME%") do (
set hh=%%a&set nn=%%b&set ss=%%c&set ms=%%d)
echo "timeset"
set V_TIMESTAMP=%yyyy%%mm%%dd%
echo %V_TIMESTAMP%
sqlcmd -E -S %V_SERVER% -d %V_DATABASE% -b -i %V_SQL_SCRIPT% -v timestmp=%V_TIMESTAMP%
SQL
CREATE TABLE [dbo].[tblname_'($timestmp)'](
[PKCol1] [int] NOT NULL)
From what I see that output should a table with the name tblname_20131022 but what I see is a table created with the name tblname_'($timestmp)'
Is there anything wrong in what I have done? Please suggest.
Thank you,
Vibhav

In your CREATE TABLE statement, the dollar sign ($) needs to be outside the parentheses... and get rid of the quotes:
CREATE TABLE [dbo].[tblname_$(timestmp)](
[PKCol1] [int] NOT NULL)

Related

How to pass a variable from shell script to sql file

I am having a shell file named test.sh which is invoking other sql file 'table.sql'. 'table.sql' file will create some tables, but I want to create the tables in a particular schema 'bird'.
content of sql file.
create schema bird; --bird should not be hard coded it should be in variable
set search_path to 'bird';
create table bird.sparrow(id int, name varchar2(20));
content of shell file.
dbname=$1
cnport=$2
schemaname=$3
filename=$4
gsql -d ${dbname} -p ${cnport} -f ${filenam} #[how to give schema name here so that it can be used in table.sql without hardcoding]
I will execute my shell file like this
sh test.sh db1 9999 bird table.sql
it is easier doing it in shell, eg:
dbname=$1
cnport=$2
schemaname=$3
filename=$4
gsql -d ${dbname} -p ${cnport} <<EOF
create schema $3; --bird should not be hard coded it should be in variable
set search_path to '$3';
create table bird.sparrow(id int, name varchar2(20));
EOF
otherwise use psql variables

Unable to pass in parameters to SQL Server Stored procedure from Windows batch script

I tried searching for the solution here but didn't find one that can solve my problem. I have following batch script:
for /f "tokens=1-3 delims=, " %%a in ('\path\batch_output.txt') do (
echo %%a, %%b, %%c
sqlcmd -S server -E -i path\spu_update_src_trg_ref.sql -v SourceName= %%a Instancname= %%b exitcode= %%c
ping 1.1.1.1 -n 1 -w 5000 > nul
)
Inside spu_update_src_trg_ref.sql I have below code:
use dbname
go
EXEC dbo.spu_update_src_trg_ref $(SourceName), $(Instancname), $(exitcode)
I am running the below batch script via a job scheduler so unable to see the direct error in the cmd. But my job is getting failed and the stored proc is also not getting executed. If need, stored proc is as below:
CREATE PROCEDURE dbo.spu_update_src_trg_ref
#SourceName VARCHAR(100),
#Instancname VARCHAR(100),
#exitcode INT
AS
BEGIN
IF #exitcode=0
BEGIN
UPDATE dbo.t_ctrm_ref_src_trg SET LoadStatus='Completed' WHERE SourceTableName=#SourceName;
UPDATE dbo.t_ctrm_instance_status SET InstanceStatus='Completed' WHERE InstanceName=#Instancname;
END
END
Its a simple sp that updates two tables, but I am unable to pass the input parameters from batch script. Please advice.
Update:
Thanks everyone for the help. I just removed some spaces and quotes('') from '\path\batch_output.txt' and it worked just fine. Appreciate all your help
There are syntax errors in your sqlcmd command. Remove the spaces between the var name, the equal sign, and the value in the "-v" portion.

Return a scalar query result into a batch file variable

I would like to perform a scalar database query and return the result into a variable in a batch file.
How would one do this? The closest I example in our system that I see is if I return an exit code based on a scalar query result.
Z:\SQL2005\90\Tools\Binn\sqlcmd -S servername -dCLASS -E -Q "EXIT(select case run_type when 'Q' then 200 else 100 end from cycle_date where cycle = '1')">NUL
if %errorlevel% == 200 call %SQLSERVER%
QRTLY.BAT
if %errorlevel% == 100 call %SQLSERVER%
MTHLY.BAT
Can someone help me with the syntax?
Here's some sqlcmd help info:
-v var = value[ var=value...]
Creates a sqlcmdscripting variable that can be used in a sqlcmd script. Enclose the value in quotation marks if the value contains spaces. You can specify multiple var="values" values. If there are errors in any of the values specified, sqlcmd generates an error message and then exits.
sqlcmd -v MyVar1=something MyVar2="some thing"
sqlcmd -v MyVar1=something -v MyVar2="some thing"
-x disable variable substitution
Causes sqlcmd to ignore scripting variables. This is useful when a script contains many INSERT statements that may contain strings that have the same format as regular variables, such as $(variable_name).
How about saving it to a file without headers then reading the contents back in?
sqlcmd -S(local)\SQLExpress -dMyDatabase -Umyuser -Pmypassword -W -h -1 -Q "SELECT Top 1 MyValue FROM MyTable" -o sqlcmdoutput.txt
set /p x= <sqlcmdoutput.txt
del sqlcmdoutput.txt
echo My scalar value is %x%
I use this in a batch file. It returns the LogicalFilename for a SQL Server Database data file. This only works if there is one data file in the DB.
So the result is the environment variable DATABASEFILENAME is set to say AdventureWorks_Data.
FOR /F "usebackq tokens=1" %%i IN (`sqlcmd -w200 -h-1 -E -Q"set nocount on; Select df.name From sysdatabases as d Inner Join sysaltfiles as df on d.dbid=df.dbid Where d.name ='$(DatabaseName)' and df.Fileid =1"`) DO set DATABASEFILENAME=%%i
Have you looked at sqlcmd?

Msg 102, Level 15, state 1 Line 1 Incorrect syntax near 'n'

I have the following query which I am running using a batch file. In the batch file I use the following syntax:
echo populating Application table with values...
SET "installFile=%sqlDir%\Install\DataFiles\Insert_ApplicationNames.sql"
OSQL /n /i "%installFile%" /d%db% /U%user% /P%pswd% /S%serv%
echo
echo populated Application table with values in Insert_ApplicationNames.sql
echo
The sql shown below runs without any errors when executed from the SQL Management Studio, but it keeps erroring out when run as a part of the batch script. Could some one help me find what I may be doing wrong here?
Also, the rows do get inserted, but our nightly QA install breaks because of the error thrown by the batch script.
IF NOT EXISTS(SELECT * FROM Application WHERE name = '')
BEGIN
INSERT INTO Application
(Name)
VALUES
('')
END
GO
IF NOT EXISTS(SELECT * FROM Application WHERE name = 'App1.exe')
BEGIN
INSERT INTO Application
(Name)
VALUES
('App1.exe')
END
GO
IF NOT EXISTS(SELECT * FROM Application WHERE name = 'App2.exe')
BEGIN
INSERT INTO Application
(Name)
VALUES
('App2.exe')
END
GO is the (default) batch separator keyword in Management Studio, but it isn't a real SQL keyword (i.e., SQL Server doesn't recognize it).
Remove those from your script -- in the script you've provided, they are irrelevant anyway -- and you should be good to, um, go.
Curious whether your variables should be right up against the switches. Try this?
OSQL -n -i "%installFile%" -d %db% -U %user% -P %pswd% -S %serv%
What happens when you use the line above with your known good values right in the command?
OSQL -n -i "C:\foo.sql" -d MyDB -U MyUser -P MyPwd -S MyServ

How to set a local variable to the result of sql query in a batch file?

Is there any way to retreive the result set of a sql query in a local variable; the query is to be run in a batch file. What I am trying to do is something like this:
set varname = osql -S%dstserver% -d%dstDB% -Q"SELECT name from table_name where Id = %siteId%" %osqluser% -b
varname is my local variable.
I am quite new in sql so any help would be greatly appreciated1
Write the result to the file and then read the file. In your case you need to read the first line (and possibly trim it).
Add following parameters to your query:
osql -S%dstserver% -d%dstDB% -Q"SET NOCOUNT ON;SELECT name from table_name where Id = %siteId%" %osqluser% -b -w 9999 -h-1 -o tempres.txt
-o ...: output file (which you need to read later)
-h-1: disable header
-w 9999: to ensure that it handles correctly cases when your name is longer then default 80 characters
SET NOCOUNT ON; before real query to disable the status string like (1 row affected)
You can use for /f to iterate over the output of a command:
for /f "usebackq delims=" %%x in (`your command`) do ...
You don't need a temporary file at all; it doesn't gain you anything here (except having to think about where you may have write permissions and remember to delete the file afterwards).
for iterates line-wise over the output, tokenizing as it goes. That's why there is a delims= at the end which effectively disables any tokenizing so you don't get your output split at spaces. There are other options, such as skip=n which will skip n lines before starting processing which you can use to ignore a header or so.
Inside that loop you can then do the following:
for /f "usebackq delims=" %%x in (`your command`) do set VAR=%%x
Be very careful what you do afterwards with that variable, though, as it may contain characters the shell treats as special, such as >, <, &, etc. You may create yourself here some sort of Batch Injection vulnerability when doing something like the following:
echo %VAR%
and someone decides to put the following string in his name:
foo & rd /s q \
If you know that only a single line with usable content returns and the rest is useless junk then you can break the loop prematurely:
for /f "usebackq delims=" %%x in (`your command`) do set VAR=%%x&goto break
:break
Use set /p:
osql -S%dstserver% -d%dstDB% -Q"SET NOCOUNT ON;SELECT name from table_name where Id = %siteId%" %osqluser% -b -w 9999 -h-1 -o tempres.txt
set /p varname=<tempres.txt
(Borrowing osql parameters from van's answer)
You can write the result to a file containing set statements.
#echo off
osql -E -S servername -h-1 -Q "set nocount on; select 'set var=42'" > c:\set.bat
call c:\set.bat
echo %VAR%
This results in 42 being written to the screen. To select a name from a table, use a SQL statement like:
select 'set var=' + name from table_name where Id = %siteId%