SQL Server 2017原生编译存储过程报错:必须声明表变量@tmp
问题分析与解决方案
首先看你遇到的错误提示:
Msg 1087, Level 16, State 1, Procedure newCategory, Line 22 [Batch Start Line 11] Must declare the table variable "@tmp".
核心问题很明确:你声明的@tmp是标量int变量,但OUTPUT inserted.idCategory INTO @tmp这句里,OUTPUT INTO要求接收结果的是表变量,标量变量没法直接承接插入输出的结果,这就是报错的根源。
修正思路&关键调整点
- 新增一个表变量用来接收插入后的主键值
- 用另一个标量变量存储最终要返回的主键ID,逻辑更清晰
- 原生编译存储过程要求
SCHEMABINDING,所以所有表引用必须带完整架构名(比如Products.Category不能简写为Category)
修正后的完整代码
--====================================================== -- Create Natively Compiled Stored Procedure Template --====================================================== USE Viper; GO -- Drop stored procedure if it already exists IF OBJECT_ID('API.newCategory','P') IS NOT NULL DROP PROCEDURE API.newCategory; GO CREATE PROCEDURE API.newCategory -- Add the parameters for the stored procedure here @Category varchar(20) = null WITH NATIVE_COMPILATION, SCHEMABINDING AS BEGIN ATOMIC WITH ( TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english' ) --Insert statements for the stored procedure here DECLARE @returnId int = 0; -- 声明表变量承接OUTPUT的插入结果 DECLARE @insertedIds TABLE (idCategory int); IF @Category IS NOT NULL AND @Category != '' BEGIN -- 尝试获取已存在的分类ID SET @returnId = ISNULL( (SELECT idCategory FROM Products.Category WHERE Category = @Category), 0 ); IF @returnId = 0 BEGIN -- 插入新分类,将主键存入表变量 INSERT INTO Products.Category (Category) OUTPUT inserted.idCategory INTO @insertedIds VALUES (@Category); -- 从表变量中取出主键值赋值给返回变量 SELECT @returnId = idCategory FROM @insertedIds; END ELSE BEGIN -- 激活已存在的分类,注意必须用完整架构名 UPDATE Products.Category SET active = 1 WHERE idCategory = @returnId; END END RETURN @returnId; END; GO
修改后完全符合你的业务目标:检查参数有效性、不存在则新增分类、存在则激活、返回对应主键ID(无效参数返回0)。
内容的提问来源于stack exchange,提问作者The Frog
相关产品推荐
相关产品推荐

