It seems like this approach for setting sqlcmd variable does not work so I am wondering if there is another way?
DECLARE #d varchar(max);
SET #d = 'foobar';
:setvar database #d
USE $(database)
Note: I realized that using :setvar in this manner works but I want to set it using a variable in the T-SQL script instead of explicitly setting it.
:setvar database "foobar"
This makes no logical sense, from the perspective of SQLCMD. :setvar is a command that lives outside the T-SQL script; it can't "see" anything the T-SQL script does at runtime. You can set the variable through any number of means, including environment variables, options and :setvar itself, but you can't mix in runtime T-SQL execution.
Rethink your script so the SQLCMD script lives "outside" the T-SQL script, and the T-SQL script does the necessary runtime actions. Since you can execute dynamic statements in T-SQL, there shouldn't be any need for setting an SQLCMD variable through T-SQL rather than the other way around.
Related
I have a variable stipulated in my SqlCmd.exe:
/v:PipelineUser=$(user)
I'm wanting to reference this from a DACPAC/Post Deploy script, but I'm not entirely sure how. The chat on the script template itself says this:
/*
Post-Deployment Script Template
--------------------------------------------------------------------------------------
This file contains SQL statements that will be appended to the build script.
Use SQLCMD syntax to include a file in the post-deployment script.
Example: :r .\myfile.sql
Use SQLCMD syntax to reference a variable in the post-deployment script.
Example: :setvar TableName MyTable
SELECT * FROM [$(TableName)]
--------------------------------------------------------------------------------------
*/
But, that looks to be physically assigning a value to variable rather than referencing a release variable.
How do I reference the PipelineUser variable passed by SqlCmd within the Post Deploy script?
Found the solution. We need to reference the variable in the DACPAC/SSDT project properties.
Then when the deploy script is created as part of SqlCmd, it just gets substituted in.
Then we can reference however we want in our post-deploy script by using $(variablename)
This is an actual object name, and not simply a string. We can make it a string though by 'quoting' it.
Example usages:
DECLARE #userVARCHAR(100) = '$(user)';
ALTER AUTHORIZATION ON SCHEMA::[Staging] TO [$(user)];
I would like to capture the output of an sqlcmd !! (operating system command) call into a variable that I can use in an insert statement. Or, just read the contents of a file into a variable.
The general idea is something like this:
:SETVAR version !! "type version.txt"
insert into dbo.DeployVersion ([Version],[Date],[User]) values ('$(version)',getdate(),'$(SQLCMDUSER)')
But it doesn't seem that I can chain SQLCMD calls in that way. Any ideas?
type version.txt just prints the content of version.txt file to the console, like cat in linux.
The best I could find was this approach, which seemed really silly.
:setvar quot "'"
declare #versionString nvarchar(300)
set #versionString =
$(quot)
:r .\version.txt
$(quot)
insert into dbo.DeployVersion ([Version],[Date],[User]) values ('$(version)',getdate(),'xyz')
This works in purely SQLCMD and is an answer to the original question.
However, this is being used in an sqlpackage deploy and I don't see a way to externally reference a version.txt file from outside of the dacpac. So instead I added a variable to the dacpac project and I specify that value on the commandline using sqlpackage ... /Variables:Version=%someValueReadFromBatFile%
I am somewhat new at this and I am having trouble. I am calling a CMD file that then calls a SQL script to execute some database commands.
The relevant CMD file code is:
set days = '360'
sqlplus #\file.sql %days%
The SQL script excerpt is:
define numOfDays = &1
EXEC (numOfDays, .....)
When executed, I get an error saying the numOfDays variable is undeclared. FYI, this is a Windows OS with a Oracle database. Any help would be appreciated and more info can be provided if needed. Thanks.
EDIT:
Added the '%' signs around the 'days' parameter that were accidentally left out.
You can try by surrounding the param with %.
e.g:
SET days=360
sqlplus #\file.sql %days%
This is how bat/cmd files recognize the variables.
I have this batch which executes on the server computer. There is a scheduled job which runs the batch. The Batch detects a particular file and then it executes an sqlcmd like below:
if not exist %TRIG_FILE% goto No_Triggers
sqlcmd
-S %WSL_SERVER%
-d %WSL_DATABASE%
-E
-Q "DECLARE #RES integer;DECLARE #RET varchar(1);DECLARE #MSG varchar(65);EXEC Ws_Job_Release 1,'Release Job Unlock Batch','All',0,0,'Unlock_Batch',#RET OUTPUT,#MSG OUTPUT,#RES OUTPUT"
My question is - how did the batch know what the %WSL_SERVER% variable is, because when I look at the script, there is nowhere in there which sets the %WSL_SERVER% variable.
This is the first time I'm reading a .bat script, I know a fair bit of programming, but I can't see how that variable was passed into this script so that it knows which server. There's no other batch calling this, it's from the batch run by the scheduler.
thanks
gemmo
Most likely the WSL_SERVER and WSL_DATABASE are global environment variables initialised every time with your Windows session. That means they exist (are defined) in every CMD session and thus in every batch script. You can open a new Command Prompt window and issue this command
SET WSL
which will (try to) display all environment variables, whether global or local, whose names start with WSL. My guess is the output will show you at least the two WSL variables used in your script.
There is a number of global variables pre-defined and maintained by the OS. Yours, however, are probably user-defined (just my guess based on the fact that my system does not have them). User-defined variables can be created by third-party software or your own (maybe someone else's) batch scripts, as well as with a standalone invocation of the SETX command:
SETX VarName "Value"
You can use that command to change the value of any of your variables globally. Note that you can also change that value temporarily only, for the duration of the script, using the SET command as usual, if global change is undesirable:
SET "VarName=Value"
In Oracle you can use &&VAR_NAME in a script and then the script will ask you for that value when you run it.
In SQLSERVER you can use $(VAR_NAME) and reference a property file using:
:r c:/TEMP/sqlserver.properties
And in the property file you have something like:
:setvar VAR_NAME_some_value
Can you do the equivalent of &&VAR_NAME so the script asks you for the value when you run it instead of having the value predefined in a script.
If I've understood correctly, you're talking about variable substitution with the SQLCMD utility.
I don't see that SQLCMD supports the behaviour you describe.
An alternative would be to exploit the fact that SQLCMD will substitute the values of system or user environment variables (see the link above), and create a wrapper CMD script which prompts the user for the variable value(s) using SET with the /P flag.
There is nothing in sql server like this, you should predefine all parameters values before using them, like this:
DECLARE #i SMALLINT
SET #i = 1
The problem with having a form pop up and ask you for the parameter is that you normally want rather more control over the nature of the form, even for an admin script. I'd use the variable substitution in SQLCMD, from within a Powershell or Python script so you can provide the guy running the script a better and more helpful form. That would make a very powerful combination.
You can do quite a lot with template variable substitution in SSMS, but that would only go so far as formulating the correct SQL to execute. you'd then have to bang the button. It would be a bit clunky outside the development environment!