使用用户定义的表类型时出现无效的数据类型

10

我是SQL Server 2008表值参数的新手。我试图通过查询创建用户定义的表。

USE [DB_user]
GO
CREATE TYPE [dbo].[ApproveAddsIds] AS TABLE(
    [Ids] [bigint] NULL
)
GO 

当我尝试在存储过程中使用表类型时

USE [DB_user]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create  PROCEDURE [dbo].[GetTopTopic]
    @dt  [dbo].[ApproveAddsIds] READONLY      
AS
BEGIN

END

我遇到了两个错误_

@dt数据类型无效
参数@dt不能被声明为只读,因为它不是表值参数。

所以我试图找出这背后的原因,因为第一条查询成功执行了,我认为是权限问题,所以尝试了以下操作:

GRANT EXEC ON TYPE::[schema].[typename] TO [User]
GO

但错误仍然存在,不知道出了什么问题。

我刚刚注意到一些奇怪的事情,在@dt [dbo].[ApproveAddsIds] READONLY后面加上,,以上述错误就被解决了,现在的错误是关于AS,说期望变量。当我编写变量代码时,旧的错误继续存在。我认为这可能有所帮助。


2
嗯...我无法重现这个问题 - 对我来说完美运行。你确定(a)你总是在同一个服务器/同一个数据库上吗?(b)你的存储过程中实际上有一个主体吗?(如果我没有在主体中添加任何语句,我会一直收到"Incorrect syntax near 'END'"的错误提示) - marc_s
1
你确定你创建了表类型:CREATE TYPE ... AS TABLE ...吗?基本上,错误信息告诉我们没有[dbo].[ApproveAddsIds]表类型。 - Bogdan Sahlean
如果您在SQL Server Management Studio的对象资源管理器中检查数据库,请转到“可编程性>类型>用户定义的表类型” - 您是否在那里看到了您的“ApproveAddsIds”表类型? - marc_s
真的很愚蠢的问题:你确定你连接到了一个2008(或更新)的数据库引擎吗?在你正在执行此操作的数据库上,通过SELECT @@Version语句可以得到什么结果? - marc_s
执行您的查询后的结果为 Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) Jun 28 2012 08:36:30。 - Hot Cool Stud
显示剩余3条评论
5个回答

23

我也经历了这个问题。

我简单地确保我已经在 SQL Server 中保存了需要的所有内容,并重新启动了 SQL Server Management Studio。

重新启动后,错误不再出现。我使用的是 SQL Server 2012,但我认为这个方法在 2008 版本上同样适用。


5
重启SSMS对我有用,适用于SQL Server 2014。同时,请确保选择了正确的数据库。 - Dan Cook
与18.3.1版本相同。看起来是一个长期存在的错误... - Noxxys
对我有效 :) - Werdo

11

我知道我来晚了,但实际上你看到的是SSMS Intellisense的问题,你可以很容易地解决它,而不需要重新启动整个SSMS。只需按下CTRL-SHIFT-R,等待几秒钟,问题就会得到解决 :)


2
我在创建一个新的用户定义表类型(UDTT)的查询窗口中,出现了同样的问题,在另一个查询窗口中尝试创建一个新的存储过程时也遇到了这个问题。根据这个问题的另一个答案,我通过重新启动SQL Server Management Studio解决了这个问题。但是,我感到很烦恼,因为我还有很多其他正在进行中的工作。
在我的情况下,我注意到SSMS中的智能感知功能用红色波浪线标出了我的UDTT的名称。我找到了以下建议...
“迄今为止最常见的情况是您的本地内存缓存过期了。如果您经常使用USE命令切换数据库,或者数据库正在其他查询窗口或其他用户更改,则这种情况可能更普遍。您可以通过按Ctrl + Shift + R或选择菜单选项Edit > IntelliSense > Refresh Local Cache来刷新缓存。与上面一样,您可能需要等待缓存完全加载,这取决于您的元数据和其他资源的大小...”
...在以下网页上...

https://www.mssqltips.com/sqlservertip/2591/troubleshooting-intellisense-in-sql-server-management-studio-2012/

这条建议在 MSDN 上得到了重复,并在此处提供了另一个建议:

https://msdn.microsoft.com/en-us/library/ms173434.aspx

“IntelliSense” 功能无法覆盖您的编辑窗口连接到数据库后由另一个连接创建的数据库对象。 我不能确定刷新 IntelliSense 缓存是否会影响实际尝试创建存储过程时抛出的错误,但由于重新启动 SMSS 可以解决问题而不需要对脚本进行其他更改,因此缓存问题听起来是正确的。

1
通过测试确认,可能不需要重新启动SMSS:(1)在一个查询窗口中创建一个新的UDTT,然后(2)尝试在另一个DECLARE语句中使用它。 UDTT会被下划线/显示为未知类型,直到(3)按下CTRL + SHIFT + R重新加载Intellisense缓存,一切都正常了。 - Charlie Joynt

1

我曾经遇到过同样的问题,它确实与IntelliSense有关。以下是我采取的步骤来解决它。我正在使用SQL Management Studio 2017。

1)在存储过程的代码编辑器窗口中,右键单击。

2)从快捷菜单中选择“启用IntelliSense”

之后,代码编辑器没有显示任何错误。希望这可以帮助你。


@Bogdan Sahlean 的这条评论实际上很有帮助。 你确认你创建了表类型:CREATE TYPE ... AS TABLE ...吗?基本上,错误信息告诉我们没有 [dbo].[ApproveAddsIds] 表类型。- Bogdan Sahlean - Arslan Elahi

0

我也可以使用相同的代码。但是在BEGINEND之间没有语句。尝试添加一些类似这样的语句

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create  PROCEDURE [dbo].[GetTopTopic](
   @dt  [dbo].[ApproveAddsIds] READONLY  
      )   
AS
BEGIN
--Write some statements here
print 'hi'
END

从给定的代码中,我没有看到任何语法错误。在begin和end语句之间有任何查询吗? - Radhamani Muthusamy
@HotCoolStud,上面的代码应该可以正常工作...你遇到了什么问题...请详细描述一下 - sk7730
当我尝试以上代码时,我遇到了错误:dt 具有无效的数据类型。参数 dt 不能被声明为只读,因为它不是表值参数。 - Hot Cool Stud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接