必须声明标量变量 "@tempTable"

本文探讨了SQL Server中使用表变量进行修改时出现的BUG,即必须声明标量变量的问题,并提供了相应的解决策略。通过实例演示了在不同操作(删除、增加、修改)中遇到的问题及解决方案。

MLGB

微软的sqlserver有一个BUG,在使用表变量进行修改时,他会提醒你:

必须声明标量变量 "@tempTable"。

 

 

 

首先

/*create table test
(
	id int identity(1,1),
	name varchar(10)
)

insert into test
	  select '222'
union select '444'
union select '455'
*/
go
declare @mytabe table(
	id int,
	name varchar(10)
)

insert into @mytabe
	   select 1,'123'
union  select 2,'123'
union  select 4,'123'
union  select 6,'123'

-- 删除 
delete from test
	where id not in
	(
		select id from @mytabe
	)
	
--(4 行受影响)

--(1 行受影响)

-- 增加
insert into test
	select name from @mytabe
	
--(4 行受影响)

--修改

update test set test.name= @mytabe.name
from @mytabe
where test.id=@mytabe.id

--必须声明标量变量 "@mytabe"。




--解决方法
update test set test.name= ta.name
from @mytabe as ta
where test.id=ta.id
--(4 行受影响)	




 

 

 

---========================= ---Creator:Ding ---CreateDate:2025-08-21 ---Intro:获取某级目录下的行销知识报表 ---========================= ALTER PROCEDURE [dbo].[LMS_KnowledgeInfoGetCatalogByLevel] @CustomerID INT = NULL, @MemberID INT = NULL, @StartTime_min DATE = NULL, @PageIndex INT = 1, @PageSize INT = 10, @CatalogLevel INT = 1, @OutPageIndex INT OUTPUT, @OutTotal INT OUTPUT AS BEGIN SET NOCOUNT ON; -- 参数校验 IF @CatalogLevel NOT BETWEEN 1 AND 4 SET @CatalogLevel = 1; -- 动态选择目录列名 DECLARE @CatalogColumn NVARCHAR(50) = CASE @CatalogLevel WHEN 1 THEN 'KnowledgeCatalogLv1' WHEN 2 THEN 'KnowledgeCatalogLv2' WHEN 3 THEN 'KnowledgeCatalogLv3' WHEN 4 THEN 'KnowledgeCatalogLv4' ELSE 'KnowledgeCatalogLv1' END; -- 动态计算时间范围(基于@StartTime_min或当前日期) DECLARE @BaseDate DATE = ISNULL(@StartTime_min, GETDATE()), @CurrentMonthStart DATE = DATEFROMPARTS(YEAR(@BaseDate), MONTH(@BaseDate), 1), @CurrentMonthEnd DATE = DATEADD(MONTH, 1, @CurrentMonthStart), @LastYearMonthStart DATE = DATEADD(YEAR, -1, @CurrentMonthStart), @LastYearMonthEnd DATE = @CurrentMonthStart, @CurrentYearStart DATE = DATEFROMPARTS(YEAR(@BaseDate), 1, 1); -- 调试输出:显示计算后的时间范围 SELECT @BaseDate AS BaseDate, @CurrentMonthStart AS CurrentMonthStart, @CurrentMonthEnd AS CurrentMonthEnd, @LastYearMonthStart AS LastYearMonthStart, @LastYearMonthEnd AS LastYearMonthEnd, @CurrentYearStart AS CurrentYearStart; -- 1. 创建全局临时表并填充数据 IF OBJECT_ID('tempdb..##TempTable') IS NOT NULL DROP TABLE ##TempTable; DECLARE @CreateTempTableSQL NVARCHAR(MAX) = N' SELECT KnowledgeCatalogLv1, KnowledgeCatalogLv2, KnowledgeCatalogLv3, KnowledgeCatalogLv4, DeveTime, PrideAmount, IfGood, Status, CustomerID, CreatorID INTO ##TempTable FROM LMS_KnowledgeInfo WHERE Status = 2 AND CustomerID = @CustomerID AND ' + QUOTENAME(@CatalogColumn) + N' IS NOT NULL AND ' + QUOTENAME(@CatalogColumn) + N' <> ''''; '; EXEC sp_executesql @CreateTempTableSQL, N'@CustomerID INT', @CustomerID; -- 2. 构建动态SQL(显式传递所有时间参数) DECLARE @sql NVARCHAR(MAX) = N' -- 创建临时表保存三部分数据 IF OBJECT_ID(''tempdb..#CurrentMonthData'') IS NOT NULL DROP TABLE #CurrentMonthData; IF OBJECT_ID(''tempdb..#YearToDateData'') IS NOT NULL DROP TABLE #YearToDateData; IF OBJECT_ID(''tempdb..#LastYearMonthData'') IS NOT NULL DROP TABLE #LastYearMonthData; -- 当月数据(显式定义所有列) SELECT ' + QUOTENAME(@CatalogColumn) + N' AS CatalogName, COUNT(*) AS DeveNumPerMon, SUM(PrideAmount) AS PrideAmPerMon, COUNT(CASE WHEN IfGood = 1 THEN 1 END) AS GoodKnowledgePerMon INTO #CurrentMonthData FROM ##TempTable WHERE DeveTime >= @CurrentMonthStart AND DeveTime < @CurrentMonthEnd -- 使用参数名 GROUP BY ' + QUOTENAME(@CatalogColumn) + N'; -- 当年累计数据(显式定义所有列) SELECT ' + QUOTENAME(@CatalogColumn) + N' AS CatalogName, COUNT(*) AS DeveNumYTD, SUM(PrideAmount) AS PrideAmYTD, COUNT(CASE WHEN IfGood = 1 THEN 1 END) AS GoodKnowledgeYTD INTO #YearToDateData FROM ##TempTable WHERE DeveTime >= @CurrentYearStart AND DeveTime < @CurrentMonthEnd -- 使用参数名 GROUP BY ' + QUOTENAME(@CatalogColumn) + N'; -- 去年同月数据(显式定义所有列) SELECT ' + QUOTENAME(@CatalogColumn) + N' AS CatalogName, COUNT(*) AS DeveNumCompare, SUM(PrideAmount) AS PrideAmCompare, COUNT(CASE WHEN IfGood = 1 THEN 1 END) AS GoodKnowledgeCompare INTO #LastYearMonthData FROM ##TempTable WHERE DeveTime >= @LastYearMonthStart AND DeveTime < @LastYearMonthEnd -- 使用参数名 GROUP BY ' + QUOTENAME(@CatalogColumn) + N'; -- 合并数据(以年度数据为主表,LEFT JOIN其他数据) SELECT y.CatalogName, ISNULL(m.DeveNumPerMon, 0) AS DeveNumPerMon, ISNULL(m.PrideAmPerMon, 0) AS PrideAmPerMon, ISNULL(m.GoodKnowledgePerMon, 0) AS GoodKnowledgePerMon, y.DeveNumYTD, y.PrideAmYTD, y.GoodKnowledgeYTD, ISNULL(l.DeveNumCompare, 0) AS DeveNumCompare, ISNULL(l.PrideAmCompare, 0) AS PrideAmCompare, ISNULL(l.GoodKnowledgeCompare, 0) AS GoodKnowledgeCompare, CASE WHEN ISNULL(l.DeveNumCompare, 0) = 0 THEN NULL ELSE (ISNULL(m.DeveNumPerMon, 0) - ISNULL(l.DeveNumCompare, 0)) * 100.0 / NULLIF(l.DeveNumCompare, 0) END AS GrowthRate INTO #TempResult FROM #YearToDateData y LEFT JOIN #CurrentMonthData m ON y.CatalogName = m.CatalogName LEFT JOIN #LastYearMonthData l ON y.CatalogName = l.CatalogName; -- 分页处理 DECLARE @Total INT = (SELECT COUNT(*) FROM #TempResult); SET @OutTotal = @Total; SET @OutPageIndex = @PageIndex; SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY DeveNumPerMon DESC) AS RowNum FROM #TempResult ) t WHERE RowNum BETWEEN (@PageIndex-1)*@PageSize+1 AND @PageIndex*@PageSize; '; -- 3. 显式声明所有参数并传递时间范围(移除@BaseDate) EXEC sp_executesql @sql, N'@CurrentMonthStart DATE, @CurrentMonthEnd DATE, @LastYearMonthStart DATE, @LastYearMonthEnd DATE, @CurrentYearStart DATE, @PageIndex INT, @PageSize INT, @OutTotal INT OUTPUT, @OutPageIndex INT OUTPUT', @CurrentMonthStart, @CurrentMonthEnd, @LastYearMonthStart, @LastYearMonthEnd, @CurrentYearStart, @PageIndex, @PageSize, @OutTotal OUTPUT, @OutPageIndex OUTPUT; -- 4. 清理临时表 DROP TABLE ##TempTable; END这个存储过程一直报错“必须声明标量变量@BaseDate和@@CurrentMonthStart”
最新发布
08-23
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值