1

我遇到了VS2010的数据库项目无法执行生成的部署脚本的一个奇怪问题,该脚本在SP的参数列表中使用了用户定义的表类型。执行部署脚本时,我收到以下错误:使用用户定义的表类型和生成的数据库部署脚本的问题

错误SQL01268:.net SqlClient数据提供:消息137,级别16,状态1,过程AppSearch,36行必须声明标量变量“@platforms”。

@platforms变量这里是一个用户定义的表型,即简单地定义是这样的:

CREATE TYPE [dbo].[IdList] AS TABLE 
(
    Id  uniqueidentifier 
); 

,我创建看起来如下存储的过程,它使用UDDT作为其参数之一:

PRINT N'Creating [dbo].[AppSearch]...'; 


GO 
CREATE PROCEDURE [dbo].[AppSearch] 
    @nameContains   nvarchar(30), 
    @descriptionContains nvarchar(max), 
    @isEditorsPick   bit, 
    @dateAddedStart   datetime, 
    @dateAddedEnd   datetime, 
    @platforms    IdList  readonly 
AS 
begin 
    select 
     l.Id as [LibraryId], 
     l.Name as [LibraryName], 
     l.Description as [LibraryDescription], 
     c.Id as [CategoryId], 
     c.Name as [CategoryName], 
     c.Description as [CategoryDescription], 
     a.Id as [AppId], 
     a.Name as [AppName], 
     a.Description as [AppDescription], 
     a.IsEditorsPick as [AppIsEditorsPick], 
     a.DateAdded as [AppDateAdded], 
     p.Id as [PlatformId], 
     p.Name as [PlatformName], 
     p.Architecture as [PlatformArchitecture] 
    from 
     Library l 
     inner join Category c    on l.Id = c.ParentLibraryId 
     inner join App a     on c.Id = a.ParentCategoryId 
     inner join AppSupportedPlatform px on a.Id = px.AppId 
     inner join Platform p    on px.PlatformId = p.Id 
    where 
      (@nameContains is not null and a.Name like '%' + @nameContains + '%') 
     and (@descriptionContains is not null and a.Description like '%' + @descriptionContains + '%') 
     and (@isEditorsPick is not null and a.IsEditorsPick = @isEditorsPick) 
     and (@dateAddedStart is not null and @dateAddedEnd is not null and a.DateAdded between @dateAddedStart and @dateAddedEnd) 
     and (@platforms is not null and p.Id in (select Id from @platforms)) 
end 
GO 

使用SQLCMD模式执行部署脚本。任何想法,为什么我得到上述错误?

在此先感谢!

+0

我想通了。接近我的脚本末尾,我检查@platforms是否为空,结果我无法做这个检查,因为它不是标量变量。我应该更多地关注错误信息,哈哈。当天的课程:TVP不是标量变量。 – ajawad987

回答

1

考虑一个表类型应该有点像一个表。你不能说“如果TABLE不是NULL”,那么为什么你应该能够说“如果TABLE TYPE不是NULL”?我没有使用台湾居民入境许可证广泛,但如何检查,该TVP不为空:

AND (EXISTS (SELECT 1 FROM @platforms) AND p.Id IN (SELECT Id FROM @platforms)); 

后者可能就足够了(同样是缺乏的台湾居民入境许可证与比什么都打以上)或可能:

AND (p.Id IN (SELECT Id FROM @platforms) OR NOT EXISTS (SELECT 1 FROM @platforms)); 
+0

感谢您的回答。我刚才已经明白了这一点。 UDDT不是标量类型,因此'非空'检查无效,因为这需要标量类型。 我不认为我甚至需要检查如果@平台变量,所以我只是删除它(现在)。 – ajawad987

+1

无论您需要它,取决于您在不使用该参数的情况下调用存储过程时想要的行为。如果你只是说'AND p.Id IN(SELECT ID FROM @platforms)',那么当空时你想要发生什么?你想检查忽略还是你想要0结果? –

+0

我想要实际忽略的检查。感谢您的意见。非常感激。 – ajawad987

相关问题