【发布时间】:2014-08-23 02:18:44
【问题描述】:
我有许多 sp 创建一个带有各种字段的临时表 #TempData。在这些 sp 中,我称其为在#TempData 上运行的一些处理 sp。临时数据处理取决于 sp 输入参数。 SP代码是:
CREATE PROCEDURE [dbo].[tempdata_proc]
@ID int,
@NeedAvg tinyint = 0
AS
BEGIN
SET NOCOUNT ON;
if @NeedAvg = 1
Update #TempData set AvgValue = 1
Update #TempData set Value = -1;
END
然后,这个sp在外层sp中被调用,代码如下:
USE [BN]
--GO
--DBCC FREEPROCCACHE;
GO
Create table #TempData
(
tele_time datetime
, Value float
--, AvgValue float
)
Create clustered index IXTemp on #TempData(tele_time);
insert into #TempData(tele_time, Value ) values( GETDATE(), 50 ); --sample data
declare
@ID int,
@UpdAvg int;
select
@ID = 1000,
@UpdAvg = 1
;
Exec dbo.tempdata_proc @ID, @UpdAvg ;
select * from #TempData;
drop table #TempData
此代码引发错误:消息 207,级别 16,状态 1,过程 tempdata_proc,第 8 行:无效的列名“AvgValue”。
但如果我取消注释声明 AvgValue float - 一切正常。
问题:是否有任何解决方法让存储的 proc 代码保持不变并向优化器提供提示 - 跳过此步骤,因为由于传递的参数,sp 不会使用 AvgValue 列。
动态 SQL 不是一个受欢迎的解决方案顺便说一句。根据现有的 tsql 代码(为此需要进行大量修改),使用 #TempData 表名的替代方案是不可取的解决方案。
试过 SET FMTONLY、tempdb.tempdb.sys.columns、try-catch wrapping 都没有成功。
【问题讨论】:
-
为不同的目的使用不同命名的表。
-
使用不同的表名可能会导致正在进行的存储过程的不可预知的行为,这也会选择/更新
#TempData#records -
那么,一张临时表被不同的procs使用,目的不同?如果是这样,您必须在临时表中有所有使用的列。有问题吗?
-
确实如此。确切的临时表用作许多 sp 之间的缓冲区。如果您想再操作一个额外的列,所有 sp 都必须添加此列以实现兼容性。问题是,如何强制数据库引擎避免未使用的不存在的列,而不是在执行时抛出错误。
-
您可以有一个用于创建/删除临时表的过程。所有列都可以为空,因此所有列都是可选的。
标签: sql tsql sql-server-2005 tempdata