SSDT 对视图的对象有一个未解析的引用,但对于过程工作正常

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

此错误不是 "normal error",因为缺少数据库引用。我正确添加了一个数据库引用,到目前为止它在存储过程中运行良好。

问题:

我有一个数据库项目,我们称它为BIDK。该数据库引用了 dacpac 文件,该文件是从另一个名为 RPTDK.

的数据库项目构建的

RPTDK 有一个 table 叫做 dbo.BILLINGITEM,我可以参考 使用此代码的 BIDK 数据库项目:

create proc CommonDM.TestReferenceFromProc
as
select BILLINGITEM_ID,
       TIMESTAMP,
       BILLINGITEMTYPE_ENUMID,
       VATCODE_ENUMID,
       LCOMPANY_ID,
       LEASESERVICECOMPONENT_ID
from [RPTDK].[dbo].BILLINGITEM as bilitm;

这很好用,我可以构建项目 BIDK。 闪亮快乐的人跳舞!

但是,如果我添加此视图,则构建失败:

create view CommonDM.TestReferenceFromView
as
select BILLINGITEM_ID,
       TIMESTAMP,
       BILLINGITEMTYPE_ENUMID,
       VATCODE_ENUMID,
       LCOMPANY_ID,
       LEASESERVICECOMPONENT_ID
from [RPTDK].[dbo].BILLINGITEM as bilitm

我无法在添加视图的情况下构建项目 BIDK,我收到错误消息:

[CommonDM].[TestReferenceFromView] has an unresolved reference to object [RPTDK].[dbo].[BILLINGITEM]

知道为什么会这样吗?

为什么它适用于存储过程而不适用于视图?

我之前有过这样的案例,不指定数据库名,尝试select不指定数据库名,像这样

select BILLINGITEM_ID,
   TIMESTAMP,
   BILLINGITEMTYPE_ENUMID,
   VATCODE_ENUMID,
   LCOMPANY_ID,
   LEASESERVICECOMPONENT_ID
from [dbo].BILLINGITEM

或像这样使用 [$DBName] 作为数据库名称

select BILLINGITEM_ID,
   TIMESTAMP,
   BILLINGITEMTYPE_ENUMID,
   VATCODE_ENUMID,
   LCOMPANY_ID,
   LEASESERVICECOMPONENT_ID
from [$RPTDK].[dbo].BILLINGITEM as bilitm

对我有用

测试并尝试不同的设置后,我可以得出结论,"correct" 方法是使用 [$(RPTDK)] 语法,其中 RPTDK 是为参数命名,因为它是在添加数据库引用时设置的。

select BILLINGITEM_ID,
       TIMESTAMP,
       BILLINGITEMTYPE_ENUMID,
       VATCODE_ENUMID,
       LCOMPANY_ID,
       LEASESERVICECOMPONENT_ID
from [$(RPTDK)].[dbo].BILLINGITEM as bilitm

这有点烦人,代码现在依赖于 SQLCMD 模式参数来工作,当你想复制并粘贴到 SSMS 时 window。

感谢 Alfin 的帮助。

ps

这在存储过程中没有失败的原因是 Visual Studio SSDT 似乎没有检查存储过程中的引用对象,而是为视图检查。我试图将引用全部删除,但存储的过程代码仍然成功构建。

简而言之 - SSDT 喜欢由两部分组成的名称。您可以为 3-4 个部件名称使用变量,但理想情况下,您应该为每个外部数据库创建 dacpac 或项目。然后在您的主项目中引用它们。然后,对于每个外部对象,您都需要创建同义词,这样您就不会遇到更多问题。此外,它还可以让您在不同的环境中使用不同的 databases/instances 名称。

您可以在我的 github repo 中找到如何使用 SSDT 组织解决方案的示例。我仍然想在那里添加更多内容,但您可以查看如何针对您的情况使用它的示例。

我知道这是一个旧话题,我没有足够的声誉来为上面的正确答案添加评论,但我想提供答案的详细信息,所以我将其作为 'answer'.

具有未知引用(相对于视图)的存储过程不能被 SSDT 引用检查器标记为错误的原因是存储过程是动态的并且会在执行期间影响模式。

换句话说,proc可以引用项目部署时不存在的TableA,但proc可以在需要使用TableA之前动态创建TableA。如果 SSDT 将未知引用标记为错误,您将永远无法构建和部署该项目。