Unable to compile SSDT Database Project with a view that has fully qualified name of table in view definition - sql-server-data-tools

We have a SQL 2019 database where all table names are fully qualified in views starting with the database name. We do NOT have the option of avoiding the fully qualified reference as the view definition is auto-generated (otherwise I would simply not fully qualify them). When views are defined by referencing tables within the same database as the view, the SSDT project complains that it has an unresolved reference.
Visual Studio does not allow adding a database reference to itself. The only way I can get it to compile is to create a DACPAC of the same database and then add that as a reference along with removing the database variable ($Name).
Is there any other method of providing fully qualified table names in views without having to create a DACPAC in SSDT project?

Only way I'm aware of would be to take the view code out of the project and handle in post-deploy scripts. This is done by design, because the database name may not be what was defined in the original code.

You can't use 3-4 part naming in SSDT normally. You can workaround this by using variables in the code. So let's say, that you have [localhost].[reports].[dbo].[your_table] you'll need to use [$(ReportServer)].[$(ReportDatabase)].[dbo].[your_table].

I have a DacPac project containing objects which use three part naming to refer to the containing database (hundreds of instances such as [thisDb].[dbo].[obj]* exist). I need compare and update this database, but the db project fails to build due to 200+ sql71561 errors.
I did not want to remove the unnecessary database name part or switch to using a database name variable. To successfully build (or compare, and then update) a database using three part naming or fully qualified naming to refer to itself, there is a way I found to pacify visual studio. It's not what I'd prefer, but it works.
Create a copy of the original db project.
In the copy db project, update all local database object references to use just two part names ([dbo].[obj]) instead of three part names (I used find & replace).
Make sure the copy db project targets the same SQL server version and builds successfully.
Reference the copy db project from the original db project (whether via database variable, database name only, or dacpac).
The original db project can now build because its references can be resolved. You'll end up with a dacpac for both the original and the copy, but at least the errors are gone and it compiles.

Related

How to incorporate OpenQuery into an SSDT project (without SQL71501/'unresolved reference to object' errors)

I have a Visual Studio SSDT project where one view references a linked server via 4 part naming. I have set up a project for the database on the linked server and created a reference from the main project to the "linked server" project, and all works fine.
I have been instructed to use OpenQuery instead of 4 part naming convention because actually OpenQuery does run 2-3x faster than query via 4 part naming convention.
However, when I change the view in SSDT to use open query, I get an error:
Severity Code Description Project File Line Suppression State
Error SQL71501: View: [schema].[view] has an unresolved reference to object [LINKEDSERVER].
I have tried defining [LINKEDSERVER] in a script in the project:
exec master.dbo.sp_addlinkedserver #server = N'LINKEDSERVER', #srvproduct=N'SQLSERVER', #provider=N'SQLNCLI', #datasrc=N'SERVERNAME'
And also tried adding same into the referenced project.
So, how to incorporate OpenQuery into an SSDT project without incurring SQL71501/'unresolved reference to object' errors?
I’ve been fighting this same issue for a while. I solved by:
Importing the master.dacpac that included the needed Linked servers.
Creating a database reference from the calling database to the DACPAC of the database I'm referencing (insure Suppress Reference Warning is checked).
used the syntax OpenQuery([LINKEDSERVER], ‘xxx’); and not OpenQuery([$([LINKEDSERVER])], ‘xxx’);
I hope this helps!

Dynamic database reference in SSDT (dacpac) project

Is there a way where the database references in a SQL Server Database project (Dacpac) can be derived at run time?
We're building a product which uses Dacpac to deploy database objects.
Our product implementation teams also use Dacpac projects by adding database reference to the product Dacpac file and then adding their own additional objects to the project.
The problem we're facing is - every time the implementation needs to point to a newer product release version, the parent dacpac references in the implementation dacpac have to be changed manually to refer to the new file path of the new product dacpac (in the newer release). We've mutiple implementation teams and multiple database projects in each implementation.
Is there any way the database references (*.dacpac) in a database project can be derived at run time using a variable or parameter or something of that sort?
My understanding of your question is as follows:
You have a SSDT database project (see example image below), that has a database reference (similar to #1 below) with stored procedures and other db objects that access the reference database (similar to file #2 and code #3). You've 'built' the solution resulting in a DACPac and now you want to take this DACPac and reference other databases at deploy-time. Hopefully I understood your question correctly.
If so, then you can use the Publish Profiles feature to achieve this (similar to #4 below).
The code for this can be seen in my notes from my SSDT talk github project.
If you look specifically at the demo04 solution file, you will see that I have a DEV_MJE.deploy.ps1 PowerShell file and a DEV_MJE2.deploy.ps1 file. These scripts run MSBuild to build the DACPac and then use SqlPackage to publish DEV_MJE.publish.xml or DEV_MJE2.publish.xml respectively. Note, if you run this example on your machine, you'll need to add MSBuild.exe and SqlPackage.exe to your path, as well as modifying the TargetConnectionString in the xml files to an existing development database.
As an example of how this works...When I use the Publish Profile DEV_MJE.publish.xml, the resulting GetDataFromAnotherTable.sql file contains:
SELECT [SomeData] FROM [AnotherDb_MJE].[dbo].[AnotherTable]
Whereas when I use DEV_MJE2.publish.xml the resulting GetDataFromAnotherTable.sql file contains:
SELECT [SomeData] FROM [AnotherDb_MJE2].[dbo].[AnotherTable]
Notice the database reference in the second has changed to AnotherDb_MJE2.
For a good description of how Publish Profiles relate to DACPacs and SSDT Database Projects, see this web page. It also contains information on alternative ways to deploy beyond SqlPackage.exe.
Something else to consider
Note, that using file paths to version control a DACPac is not really the best practice. Consider the DACPac artifact as similar to a .Net DLL. It is the biproduct of a build.
As such, a better approach is to use NuGet and tools like Octopus Deploy to store, track, and deploy DACPacs. See the stackoverflow answer for a good description of how this works.
Hope that this helps,
Michael
Thanks for the followup comment, I think what you are trying to do is when you write and deploy your code be able to use different dacpacs depending on the project?
Each implementation team might have a different version of the shared dacpac deployed so you can't just put the files in a shared location and call the dacpac "Product_Latest.dacpac" or something, so everyone always gets the latest version.
".sqlproj" files are standard msbuild scripts and references can be managed using msbuild properties so you can technically change the reference at runtime. If you edit your .sqlproj file and add a property in the first <PropertyGroup> tag, I used:
<ProdDacpacVersion Condition="'$(ProdDacpacVersion)' == ''">v1</ProdDacpacVersion>
v1 is the unique name for the version folder - you just need something to identify the dacpac you want.
I put the property just after TargetDatabaseSet and IncludeCompositeObjects.
If you then find the reference to the dacpac and instead of
<ArtifactReference Include="..\..\..\..\..\Desktop\prod\v1\Database2.dacpac">
<HintPath>..\..\..\..\..\Desktop\prod\v1\Database2.dacpac</HintPath>
<SuppressMissingDependenciesErrors>False</SuppressMissingDependenciesErrors>
</ArtifactReference>
Use the property from above:
<ArtifactReference Include="..\..\..\..\..\Desktop\prod\$(ProdDacpacVersion)\Database2.dacpac">
<HintPath>..\..\..\..\..\Desktop\prod\$(ProdDacpacVersion)\Database2.dacpac</HintPath>
<SuppressMissingDependenciesErrors>False</SuppressMissingDependenciesErrors>
</ArtifactReference>
Then the reference will use the property to get the path of the dacpac. There are a few ways you can set the property, you could edit the .sqlproj file when you want to take a new version of read the property from a file or environment variable or something (i'll leave the msbuild fun to you!).
I would, as a standard, everytime the reference was changed either reload the project or restart visual studio - it won't take long and it will save lots of cursing :)
When you deploy the dacpac's, the deploy looks in the same folder for references first so just make sure you copy the right one into the bin folder when you deploy.

How to Update Edmx file using Code

I've created a Db and created a .edmx file, using Database first approach. In development, I've used "Update model from Database", if any new field added/ size modified. How can i update the model using code like in production environment.
Any Code alternative for updating model, when database changes.
Please suggest me.
In database first approach, you want to create a separate database project (so that the changes won't affect the other projects).
Once database is changed, you just use 'Update model from Database' as you stated.
Then compile the application and copy the database project dll file to production.
Basically, you are just replacing the old dll file with new one.
Note: if your database and web application are in a same project, you'll need to copy the entire dll file.

Database using Sqlite in C# windows phone 8

I have doubt regarding windows phone 8 application development. The database using sqlite for windows phone 8 is pre-loaded into the application or it should be created dynamically at the time of installation in windows phone..? and if it is pre-loaded then how to create the database.db file..?? and also if it is dynamically created, what is the procedure to create dynamically...??
I would say, pre-loaded into the application is the very common way.
Take a look at this article, I think the steps to accomplish your task are quite the same: http://wp.qmatteoq.com/import-an-already-existing-sqlite-database-in-a-windows-8-application/
The first step is to copy your database in to the Visual Studio project and, from the Properties window, set the Build action to Content.
Once you’ve done this operation, you’ll be able to access to the files embedded in your project thanks to the Package.Current.InstalledLocation object that is available in the Windows.ApplicationModel namespace.
The InstalledLocation’s type is StorageFolder, which is the base class of all the folders mapping in WinRT: for this reason, it exposes all the standard methods to interact with the storage, like getting a file or a folder. This way we can use the GetFileAsync method to get a reference to the database embedded into the project and, after that, using the CopyAsync method we can copy it into the local storage of the application. We can copy it in the root of the local storage (like in the following example) or in a specific folder, by getting a reference to it first using the GetFolderAsync method.
For those who are not able to work with sqlite I would like to suggest them to follow this link : http://dotnetslackers.com/articles/silverlight/Windows-Phone-7-Native-Database-Programming-via-Sqlite-Client-for-Windows-Phone.aspx and when you are dumping the data into the project .. you just need to change the properties of the "database1.sqlite" i.e. Build Action = resource . Thats all you need to do ..

MyGeneration.dOOdads problem with MySQL connection in ASP.net with stored procedures

I am using MyGeneration.dOOdads which helps in generating Business layer and Data layer easily, but currently I am facing a problem with it.
I had worked with MS SQL database and was successful, but now I have to work with MySQL 5.
I have the generated data layer classes of MySQL database successfully, but when I add them in my project along with the reference of MyGeneration.dOOdads dll file it gives error of no MySql4Entity class in the namespace.
I have generated the class according to the given instructions and also added the reference of mysql.data in the project but still this error is occuring.
Please guide me if you have used MyGeneration.doodads for MYSQL5 database in asp.net.
Also please tell me how to make stored procedure using MyGeneration.doodads of MYSQL database?
open doodads project (source code) .. right click on MySql4Entity class (and other classes related to mysql) and choose 'properties' the choose build action as 'compile' from the list ... to compile the file then build the project and it its output as reference to your project ...

Resources