Using SqlCmd variable in PostDeploy DACPAC script - sql-server

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)];

Related

SSMS / SQLCMD batch to create all stored procedures within a sub-folder

I developped the following T-SQL script with a bit of SQLCMD to call separate stored procedure script for their creations. The stored procedures are located in a child Store Procedure\ folder (I want to keep the space).
They are probably better ways to perform it, but I wan to a unique script (but using files) which creates the database, the tables, the stored procedures and so on.
I detail neither the the database, nor the table scripting.
/* Create database (I still have some issues with dropping it (existing connections) */
*/ Create tables with constraints... */
-- Is it possible to declare a relative path (here MY_PARENT_PATH is replaced by "c:\...")
:setvar STORE_PROCEUDRE_PATH "[MY_PARENT_PATH]\Stored Procedures"
-- Calls CRUD stored procedures from separate scripts via SQLCMD - is it possible to batch it with all spXXX_XXXX.sql files included in the sub-folder?
:r $(STORE_PROCEUDRE_PATH)\spFields_Create.sql
:r $(STORE_PROCEUDRE_PATH)\spFields_Read.sql
:r $(STORE_PROCEUDRE_PATH)\spFields_Update.sql
:r $(STORE_PROCEUDRE_PATH)\spFields_Delete.sql
-- Idem for other table, such as Features, Values, etc.
Is it possible to loop all files spXXX_XXXX.sql files within the Store Procedure\ folder and execute the :r $(STORE_PROCEUDRE_PATH)\spXXX_XXXX.sql scripts?
I came accross several articles which show example using a FOR construct, but I got confused.
Thanks for any insights :-)
yes there is a way ,
SQLCMD is not able to loop through files but you can use Windows Batch Scripting to accomplish that.
here is a good blog about how to do it :
SQLCMD and Batch File magic
so basically you need to make a .bat file ex: CRUDE.bat and edit and paste below code in it and save it ,
##echo off
cd "[MY_PARENT_PATH]\Stored Procedures"
FOR %%A IN (*.SQL) DO ( sqlcmd -S [SERVERNAME] -d [DATABASE] -U [][username -P password] -i "%%A")
you need to replace these values with your values :
MY_PARENT_PATH : Your path or Directory where your suborder is.
SERVERNAME : Your Database Server Name.
DATABASE1 : Your Database name.
Username : Your SQL Username.
Password : Your SQL Password.
now you can run the batch file and it does the magic.
also here you can find out more about SQLCMD utility

SQLCMD - Capture output from Operating System Command as variable

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%

Passing parameters from CMD file to SQL script

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.

Setting sqlcmd variable using tsql variable

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.

sql server - setting variables at runtime

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!

Resources