Scripting FileTables - database

Scenario:
I have 3 environments that I am using, Dev, UAT and Live. Each of which having it's own database, MyDb_Dev, MyDb_UAT, MyDb_Live.
Then I have a VS2012 Database project in my solution that contains all my scripts. This works nicely when I make changes to my model database (MyDb_Model) that is located locally.
What I want to do:
I want to use the FileTables in SQL 2012 (which I understand how to set up), however I don't know how to script them to be able to configure the options to handle my environments. When I generate the scripts, it will hard code the name to be MyDb_Model as the FileGroup. Also, that said, when I do try and publish to my Dev database, it's complaining about the database options not being able to take the new scripts. When I script include the options of the Model database, it'll complain when I try to publish to my Dev database because of duplicating names.
Question:
Can you script FileTables (with the database options) using the database project in V2012 to be configurable or do I need to manually make my own scripts?
Prefered:
Compare MyDb_Model to Database project.
Publish to MyDb_Dev as a newly created database.

Sounds like you'll want project variables to handle this where the variable contains the environment-specific text for each. You'd then use that variable in your objects instead of the hard-coded paths. The following would create a FileTable called "DocumentStore" and use the value for a variable called "FileTableDirectoryVariable" that you set up in your Project Properties - SQLCMD Variables. Set each of those in your Publish Profiles to use the correct directory, and you should be good. If you're using different filegroups for these tables, you should be able to tweak the FileGroup setting in a similar manner using a SQLCMD Variable.
CREATE TABLE DocumentStore AS FileTable
WITH (
FileTable_Directory = '$(FileTableDirectoryVariable)',
FileTable_Collate_Filename = database_default
);
GO

Related

Access Build variables inside Pre and Post deployment scripts SSDT

I have just set up an SSDT project which I want to use to create local databases on the SQL server hosted locally on my machine.
I want to add some pre- and post- deployment SQL scripts for initialization and cleanups.
Since, the server and the database name can change, I have defined two build variables using the project properties each for the target server and target database.
However, I can't seem to access them inside the post deployment scripts.
The syntax below won't build the project -
use [$(TargetDatabaseName)]
This builds, but then fails while publishing -
use ['$(TargetDatabaseName)']
and the error says the ''myTargetDB'' doesn't exist (myTargetDB was passed as a value at the time of publishing)
This might be a trivial thing but I am just not able to get around it. I am on SQL server 2016 if that matters.
Make sure that you put both scripts in SQLCMD mode. See the image below surrounding with red.
Once your target variable is defined, see surrounding with blue in the image above, it can be safely used in the PostDeployment script, see the image below surrounding with blue.
If you have any questions, feel free to contact me.
There is a predefined variable, $(DatabaseName), for the name of the target database. You don't need to create your own; and even if you do, you would need to set the same value to both of them.
Not sure about the target server. In most cases, SQL scripts are generated with the assumption that connection to the correct server is already established. Sure, you can change the current server using something like :connect $(TargetServerName), but I think it will only lead to confusion (and I'm not sure it will work, actually).
The only exception I can think of is that you can't use SQLCMD variables to parameterise the logical/physical names of the database files - these have to be hardcoded.
All other variables, if declared in the project properties, should be accessible everywhere. Below is a fragment of a post deploy from one of my projects:
use [master];
go
print 'Switching database ownership to sa...';
GO
alter authorization on database::[$(DatabaseName)] to [sa];
go
use [$(DatabaseName)];
go
print 'Creating database master key...';
go
-- Create database master key
create master key encryption by password = '$(DMK_Key)';
go
print 'Running database setup...';
go
exec dbo.init_database;
go
It is possible, however, that you are trying to reference another database, located on a different server. If that's the case, you need to follow a different approach, namely: built a project for that remote database and add its DACPAC to the list of project references, using the Add database reference... menu. There, you will be able to specify variables for both the (linked) server and the database name.

How to create database using Database Project in Visual Studio if doesn't exists?

I have a Database project for my personal project and I am trying to deploy my code to my DEV server. I frequently delete and re-create my DEV Server. Right now, DEV Server is newly created with SQL Server. Every time I want to deploy my code I have to manually create Database Project and then publish database project. I want to automate creation of Database with database project deployment.
Right now, I have a script that creates database, but I have to execute it manually. And this is working perfectly but I want to automate this step as well.
Is this even possible? If yes, then how? Please explain step by step. Also what will we mention for Initial Catalog in connection string?
Edit:
I tried to create Database by using
CREATE DATABASE LocalDbTest
in Pre-Deployment Script. But it didn't work. It is creating Database, but then tables are not getting created tables under it. Since I used master database as default database, it is creating table under master. It is not letting me select LocalDbTest database as default because it is not yet created, so I have to select Master as my default database. I tried to Change Database by:
USE LocalDbTest
GO
I used it just after creating Database but this didn't work because when generating script it is changing back to default database. This part is coming automatically when generating script.
USE [$(DatabaseName)];
GO
Also Visual Studio is not letting me add database name in front of table name like:
CREATE TABLE [LocalDbTest].[dbo].[TestTable]
I am getting error:
When you create an object of this type in a database project, the object's name must contain no more than two parts.
If you have a script ready for database creation, you can use the Pre-build event to call SQLCMD and run your script.
Edit:
If you have trouble pointing to a database that does not exist, you may have to manually edit the publish profile (ex. dev.publish.xml) and set the TargetDatabaseName element explicitly. You can also set CreateNewDatabase element to True if you want to be recreated every time it gets published.
Answer:
You can use a publish profile and hardcode the target database in it.

how to mirror a whole database cluster in postgresql

I'm using a postgresql (9.6) database in my project which is currently in development stage.
For production I want to use an exact copy/mirror of the database-cluster with a slightly different name.
I am aware of the fact that I can make a backup and restore it under a different cluster-name, but is there something like a mirror function via the psql client or pgAdmin (v.4) that mirrors all my schemas and tables and puts it in a new clustername?
In PostgreSQL you can use any existing database (which needs to be idle in order for this to work) on the server as a template when you want to create a new database with that content. You can use the following SQL statement:
CREATE DATABASE newdb WITH TEMPLATE someDbName OWNER dbuser;
But you need to make sure no user is currently connected or using that database - otherwise you will get following error.
ERROR: source database "someDbName" is being accessed by other users
Hope that helped ;)

SQL Compare Command-line does not synchronize database

In order to automate database synchronization using the SQL Compare command line; I have created a project to compare and deploy from my local database to a database in another server. Then I create a bat file. here is my bat file:
SET curdir=%~dp0
SET sqlcompare="C:\Program Files (x86)\Red Gate\SQL Compare 13\sqlcompare.exe"
%sqlcompare% /project:"%curdir%IcLoyalty.scp" /sync /include:Identical
The result of command is:
Registering data sources
Creating mappings
Comparing
Summarizing Project Selections
Retrieving migration scripts
Checking for identical databases
Creating SQL
Deploying changes (from DB1 to DB2)
When I check the destination database the changes does not apply. Consider that project work correctly when I open it with SQL Compare Application.
What I've missed in bat file?
It's possible that you had your selection (the checkboxes on the comparison results) deselected when you saved the project. Try selecting them all and resave the project.
This is from the documentation page.
"If you want to include or exclude objects from an existing project, you must modify your selection using the graphical user interface."

Visual Studio 2010 Database Project Deploy to Different Environments

I've got a Database project which works fine for my local MSSQL 2008 database.
It has a script under scripts/post-deployment that inserts standing data configuration into a settings table, and other tables. I've got 1 file for each table, e.g. a Setting.sql file to insert data into the Settings table.
The settings will be different depending on the database I deploy to.
How can I script this? Basicaly I would like to be able to have say 2 files,
Prod.Setting.sql and Dev.Setting.sql and VS 2010 would use the appropriate script depending on what database (environment) I am deploying to.
Completely doable but there two options and a few steps involved. You can have a complete duplicate set of scripts, one for each configuration. Or, you can have one set of scripts, the contents of which take into account the configuration you are using. I'll go with the first, and I'll keep it simple.
Create two solution configurations, or use Debug and Release if you like. I'll use these for the example.
For each configuration, create a new .sqlcmdvars file.
Database_Release.sqlcmdvars
Database_Debug.sqlcmdvars
Switch your solution configuration to each and in the database project properties change the variables file drop down to point at the corresponding file you created.
In each of those files you can define variables to be used during deployment. Create a new variable in each one
$(DeploymentConfiguration)
And set its value in each one to either Debug or Release
Then in any of your Pre or Post deployment scripts you can do something like so:
IF '$(DeploymentConfiguration)' = 'Debug'
BEGIN
PRINT 'Executing Debug deployment'
:r .\Debug\SomeNeededScript.sql
END
IF '$(DeploymentConfiguration)' = 'Release'
BEGIN
PRINT 'Executing Release deployment'
:r .\Release\Anotherscript.sql
END

Resources