SQL Server Project View references tables from different Database - sql-server

I am converting a database model into a SQLModel so we can start deploying with a dacpac. I have completed this with a few other databases but none references external databases. I have an issue where a couple views and stored procedures reference tables from a different database that is be on the same server. For stored procedures there isn't an error because procedures do not need to have the tables created unitil runtime. But for the views I get build errors for
contains an unresolved reference to an object. Either the object does
not exist or the reference is ambiguous
I have been trying to figure out a way to make it work without having to have a second project that has the fields in place or to reference a different dacpac. I co-worker suggested to try synonyms but that didn't solve the problem either.
Any help would be greatly appreciated.

You will need to create additional SQL projects and import the other dbo's for each external database reference. Then, create references in your main project to the additional (external ref) projects. You will probably have to find/replace any three-level references in your main db (maindb.schema.object -> schema.object) that reference the main db as well. FINALLY, build the solution and if it is error-free your reference errors should clear up.
You can use the error codes reported (71561, 71501) to search around for how other people have resolved this, but the above steps worked for me.

I just ran this on two databases (local and external database named x6 on SQL Server 2012)
create view dbo.view1
as
select * from dbo.x5 inner join x6.dbo.t2
on dbo.x5.i1 = x6.dbo.t2.x1
;
go
create view dbo.view2
as
select * from dbo.x5 inner join x6.dbo.t2
on dbo.x5.i1 = x6.dbo.t2
View2 was not created because I did not refer to the column that was used to join to table x5 with a message of:
The multi-part identifier "x6.dbo.t2" could not be bound.
So it worked when I was explicit about columns used to join. Also if there are duplicate names in the two tables it could get confused.
If there are a column named state1 in both tables and you do a select name1 from.... if will give you an ambiguous reference error.

Related

Using CHANGETABLE() in SSDT Visual Studio 2019 results in unresolved reference to object

I'm in the process of migrating a bunch of existing databases to a Visual Studio project so it can be put in source control. Unfortunately there is 1 stored procedure which uses a table on which change tracking is enabled. It contains a left join to the following nested select statement:
(select distinct ch.batch_number from CHANGETABLE(CHANGES dbName.dbo.batchTable, 0) as ch)
This gives the following warning:
SQL71562: Procedure: [dbo].[stMergeBatchInfo] contains an unresolved reference to an object. Either the object does not exist or the reference is ambiguous because it could refer to any of the following objects: [CT].[batch_number] or [CT].[ch]::[batch_number].
It indicates that the column ch.batch_number is unknown. It appears that when the CHANGETABLE function is used the column definition is unknown to the project. The table being read is referenced through a DACPAC file and can be used in standard SELECT statements just fine.
Does anyone know if there any way to get rid of these build warnings? Target SQL server is 2016. The database and table names are dummy names by the way.
I had a similar issue and actually came here looking for an answer. There are 2 things that might help
Make sure you have master referenced in your proj. under the proj right click references and add system master.
I did a schema compare from the db to the project and noticed my table was missing 'ALTER TABLE [dbo].[History_Table] ENABLE CHANGE_TRACKING'
I hope either of these help you out.
I've encountered this before. In my case, the version of the master database reference didn't match the version of the Database Project.
In my sqlproj file, the version of the database is 2014 (120).
<DSP>
Microsoft.Data.Tools.Schema.Sql.Sql120DatabaseSchemaProvider
</DSP>
Next, ensure your master database reference is the same version (120).
<ArtifactReference Include="$(DacPacRootPath)\Extensions\Microsoft\SQLDB\Extensions\SqlServer\120\SqlSchemas\master.dacpac">
<HintPath>
$(DacPacRootPath)\Extensions\Microsoft\SQLDB\Extensions\SqlServer\120\SqlSchemas\master.dacpac
</HintPath>
<SuppressMissingDependenciesErrors>
False
</SuppressMissingDependenciesErrors>
<DatabaseVariableLiteralValue>
master
</DatabaseVariableLiteralValue>
</ArtifactReference>
Thanks

DB View in DB project in Visual Studio can't see synonym in same project

Our web app uses 4 databases, all on the same server.
The SQL for these databases is stored in 4 projects in our solution.
I have a view in one database that is used in two other databases.
Both of those databases have a synonym to the view, WITH THE SAME NAME. From a database perspective, it makes perfect sense.
[database_1].dbo.Syn_AAAAAA and [database_2].dbo.Syn_AAAAAA both point to [database_3].dbo.vw_AAAAAA.
From a sql server perspective, it makes perfect sense.
Application works fine. Databases are quite happy.
Database1 uses the [synonym ==> view] in stored procedures, and everything is fine. When the code is in the db project, it is fine too.
In database2 PROJECT, I reference the [synonym ==> view] in another view. Of course, works fine in the data base.
BUT in the project, the view that uses the synonym is choking. It's like it is seeing ALL synonyms with that name, even those outside of it's scope, the database it's in.
select y.columnA, y.columnB, y.columnC, _l.columnD_, d3.columnE, d3.columnF
from dbo.TableD d3
inner join (subquery) y
on y.columnA = d3.columnA
left join _dbo.syn_AAAAAA_ l
on _l.columnC_ = d3.columnC
(Underscores denote the error locations from IntelliSense.)
If I can write competent SQL code on the server, why do I have to fight with Visual Studio about storing it in a project?
SQL71501: View: [dbo].[vw_AAAAAA] contains an unresolved reference to an object.
Either the object does not exist or the reference is ambiguous because it could refer to any of the following objects:
[$(ThisDB)].[dbo].[Syn_BBBBBB].[l]::[ColumnName],
[$(ThisDB)].[dbo].[Syn_BBBBBB].[ColumnName] or
[dbo].[Table].[l]::[ColumnName].
SQL71561: View: [dbo].[vw_AAAAAA] has an unresolved reference to object
[$(ThisDB)].[dbo].[Syn_BBBBBB]
Problem lay with the SYNONYM.
CREATE SYNONYM [dbo].[syn_xxxx] FOR [DBName].[dbo].[vw_xxxx]
Had to change it to
CREATE SYNONYM [dbo].[syn_xxxx] FOR [$(DBNameVariable)].[dbo].[vw_xxxx]
Most of the time [DBName] worked, but in this case I had to use the [$(DBNameVariable)].
right click on your db reference, look at the database you're trying to reference, and see if there is a variable for it. (I didn't set this up, so it's a little outside my experience.) My last position, we didn't keep SQL projects in our code solution.

SSDT has an unresolved reference to object for views but works fine for procedure

This error is not the "normal error", when there is a missing database reference. I have a database reference added correctly, and it worked fine so far with stored procedures.
The problem:
I have a database project, let's call it BIDK. This database has a reference to dacpac file, build from a nother database project called RPTDK.
RPTDK has a table called dbo.BILLINGITEM, which I can reference from BIDK database project using this code:
create proc CommonDM.TestReferenceFromProc
as
select BILLINGITEM_ID,
TIMESTAMP,
BILLINGITEMTYPE_ENUMID,
VATCODE_ENUMID,
LCOMPANY_ID,
LEASESERVICECOMPONENT_ID
from [RPTDK].[dbo].BILLINGITEM as bilitm;
This works fine, and I can build the project BIDK. Shiny Happy Poeple Dancing!
However, if I add this view, then the build fails:
create view CommonDM.TestReferenceFromView
as
select BILLINGITEM_ID,
TIMESTAMP,
BILLINGITEMTYPE_ENUMID,
VATCODE_ENUMID,
LCOMPANY_ID,
LEASESERVICECOMPONENT_ID
from [RPTDK].[dbo].BILLINGITEM as bilitm
I cannot build the project BIDK with the view added, and I get the error message:
[CommonDM].[TestReferenceFromView] has an unresolved reference to object [RPTDK].[dbo].[BILLINGITEM]
Any idea why this is happening?
Why is it working for stored proc and not for views?
I had a case like this before, instead of specifying database name, try to select without specifying the database name like this
select BILLINGITEM_ID,
TIMESTAMP,
BILLINGITEMTYPE_ENUMID,
VATCODE_ENUMID,
LCOMPANY_ID,
LEASESERVICECOMPONENT_ID
from [dbo].BILLINGITEM
or using [$DBName] for the database name like this
select BILLINGITEM_ID,
TIMESTAMP,
BILLINGITEMTYPE_ENUMID,
VATCODE_ENUMID,
LCOMPANY_ID,
LEASESERVICECOMPONENT_ID
from [$RPTDK].[dbo].BILLINGITEM as bilitm
it worked for me
After testing and trying different settings, I can conclude that the "correct" approach is to use the [$(RPTDK)] syntax, where the RPTDK is the name that of the parameter, as it is set when one adds the database reference to begin with.
select BILLINGITEM_ID,
TIMESTAMP,
BILLINGITEMTYPE_ENUMID,
VATCODE_ENUMID,
LCOMPANY_ID,
LEASESERVICECOMPONENT_ID
from [$(RPTDK)].[dbo].BILLINGITEM as bilitm
It is a bit annoying, and the code is now dependent on a SQLCMD mode parameter to work, when you want to copy and paste into a SSMS window.
Thanks Alfin for the assistance.
ps
The reason why this is not failing in a stored proc, is that it seems to be that Visual Studio SSDT is not checking for referenced objects in a stored proc, but does it for views. I tried to remove the reference all togetger, and the stored proc code still managed to build succesfully.
To be short - SSDT likes 2-part names. You can use variables for 3-4 part names, but ideally you should create either dacpac or project for each external database. Then reference them in your main project. Then for every external object you need to create synonyms and then you'll not have more problems. Moreover it will give you possibility to have different databases/instances names on different environments.
You can find an example how to organize the solution with SSDT in my github repo. I still want to add some more stuff there, but you can see an example how to work with it for your case.
I know this is an old thread, and I don't have enough reputation to add a comment to the correct answer above, but I wanted to supply a detail to the answer so I'm entering it as an 'answer'.
The reason stored procedures with unknown references (as opposed to views) cannot be flagged as errors by the SSDT reference checker is that stored procedures are dynamic and can affect the schema during execution.
In other words, a proc could reference TableA which does not exist when the project is deployed, but the proc could dynamically create TableA before it needs to use it. If SSDT flagged the unknown reference as an error, you could never build the project and never deploy it.

VS 2012 Database Project "unresolved reference to object" Error

I created SQL Server Database Project in VS 2012 & imported our database.
When I build the project, I get a lot of "unresolved reference to object" Errors.
These errors are only for a few views I have in my database.
The syntax for these views are correct & I am not using temp tables.
What should I check to solve this issue?
UPDATE:
This is one example:
CREATE view [Factory].[NonStartedOrders]
as
SELECT
"Customers"."CustomerName", "Customers"."CustomerAName",
"Customers"."MarketID",
"Orders"."OrderID",
"Orders"."ApproveDate",
"FactoryOrders"."FactoryID",
"FactoryOrders"."EstEndDate",
"FactoryOrders"."StatusID",
"FactoryOrders"."TotalWeight",
"Karats"."KaratEName"
FROM (("Taiba"."Sales"."FactoryOrders" "FactoryOrders"
INNER JOIN "Taiba"."Sales"."Orders" "Orders" ON "FactoryOrders"."OrderID"="Orders"."OrderID")
INNER JOIN "Taiba"."General"."Customers" "Customers" ON "Orders"."CustomerID"="Customers"."CustomerID")
INNER JOIN "Taiba"."MasterPiece"."Karats" "Karats" ON "Orders"."MKaratID"="Karats"."KaratID"
"Taiba" here is my database name.
I am getting 30 errors only for this view.
These are a few errors of them:
Error 217 SQL71561: View: [Factory].[NonStartedOrders] has an unresolved reference to object [Taiba].[Sales].[FactoryOrders]
Error 219 SQL71561: View: [Factory].[NonStartedOrders] contains an unresolved reference to an object. Either the object does not exist or the reference is ambiguous because it could refer to any of the following objects: [Taiba].[Sales].[FactoryOrders].[FactoryOrders]::[OrderID], [Taiba].[Sales].[FactoryOrders].[OrderID] or [Taiba].[Sales].[Orders].[FactoryOrders]::[OrderID].
One other possibility is that the schema you have used in your view/table etc does not exist in the project. You may need to add the schema to the VS Database Project.
Right Click the project and Add > New Item > Schema
I solved this issue.
It seems a few of my views/SPs have referenced the tables using this naming convention ( 3 parts qualified name ):
DatabaseName.SchemaName.TableName
I changed all references to be as the following:
SchemaName.TableName
In my case, the function that couldn't be found was of Build Action=None and so it wasn't being included in the compile.
Changing the Build Action to Build corrected this.
This happened to me when building a CTE in Visual Studio 2015. I changed the Build Action to Compile and the errors went away.
Select the file(s) with the error
Press F4 to see the properties.
Select 'Compile' in the Build Action drop down list.
Hope this helps someone.
To reference another sqlproj's schema and use three-part naming, modify your .sqlproj file to add a DatabaseVariableLiteralValue element on the referenced project.
In within the element like
<ProjectReference Include="..\SomeDatabaseProject\SomeDatabaseProject.sqlproj">, add the following:
<DatabaseVariableLiteralValue>SomeDatabaseProject</DatabaseVariableLiteralValue>
For example:
<ProjectReference Include="..\SomeDatabaseProject\SomeDatabaseProject.sqlproj">
<Name>SomeDatabaseProject</Name>
<Project>{some-project-guid}</Project>
<Private>True</Private>
<DatabaseVariableLiteralValue>SomeDatabaseProject</DatabaseVariableLiteralValue>
</ProjectReference>
Then you can use clean, three-part naming references like SomeDatabaseProject.SomeSchema.SomeTable.
It is possible that the objects are inside NotInBuild tag in the project file for naming or other issue. In my case I saved the file with ..sql and the extra dot was causing it to move under NotInBuild tag inside project file. I corrected the extension and moved the missing object under build tag and that resolved the issue.
Try explicitly defining the class:
class: Specifies the class of the securable on which the permission is being
granted. The scope qualifier :: is required.
Read the docs on the SQL GRANT statement: http://technet.microsoft.com/en-us/library/ms187965.aspx
In my case I had a User Defined Table Type.
GRANT EXECUTE ON TYPE::[dbo].[MessageTableType] TO [PostOffice_Role];
You will also get this error when you add a table (using .sql file ) and if you do not check-in the .sqlproj file
This may be an edge case but if in your object definition you are also documenting the object (we do, anyway...) using sp_addextendedproperty you can also get this error if you have stated an incorrect object type - which can happen if copy & pasting. The "unresolved reference to object" error makes sense here when you think about it.
For example the following will recreate the error as the level1type should be 'PROCEDURE' and not 'FUNCTION'.
EXEC sp_addextendedproperty
#name = N'MS_Description',
#value = N'Description of the stored procedure...',
#level0type = N'SCHEMA',
#level0name = N'dbo',
#level1type = FUNCTION',
#level1name = N'spMyStoredProcedureName'
GO
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, (properly) compare, and then update a database using three part naming or fully qualified naming to refer to itself, there is a way to pacify visual studio:
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.
The original db project can now be used to update the actual database in SQL Server after a compare.
A recompare after the update shows a flawless victory.

VS 2010 Database Project - SQL03006 Error

I created a new SQL Server Database Project within VS 2010, imported the database objects and settings from a local database named "managers", and received the following error while attempting to build the project:
SQL03006: View: [dbo].[vw_mlFunds] has an unresolved reference to object [managers].[dbo].[mlfunds].
I don't know why this view is fully qualifying a table reference to include the actual database name and I would prefer not to have to change the sql, as it someone else's code and it technically is not incorrect. But I am thinking that fully qualifying the table name to include the name of the database is confusing the VS compiler, since it is expecting [dbo].[mlfunds], not [managers].[dbo].[mlfunds]. How best to resolve this issue? Can I set up a new database name variable/alias somewhere? Or will I have to refactor/modify the sql to get it to compile? Thanks in advance.
Actually, it looks like the code will have to be modified, as this is not supported. Answer found in this post:
Using local 3-part names in programmability objects
I was getting the same error after creating a project and importing a DB. The issue for me was that the FROM table reference included the fully qualified name, but the selected fields did not; as follows
SELEC l.UserID, l.Email, m.DOB, ...
FROM ***[DBName].dbo***.Layout as l
LEFT OUTER JOIN masterUs as m
I modified the fully qualified reference by removing the DBName and DBO portion and all errors were resolved
SELECT l.UserID, l.Email, m.DOB, ....
FROM Layout as l
LEFT OUTER JOIN masterUs as m
You need to create another database project for the [managers] database and have your project 'reference' the other project. You can do this as a simple reverse-engineer step on the [managers] database that will import all the objects in that database into a new VSDB project. See Using References in Database Projects.

Resources