日期:2014-05-18  浏览次数:20686 次

SQL的变量生存期的问题,

  有一个自定义函数,根据ID返回一个表变量,
  在下面的存储过程的循环内,声明一个和返回表有相同结构的表变量。在每次循环时根据游标的变化ID,传入自定义函数,
将返回的表插入到声明的表变量中。然后经过计算后,将结果插入另一张表。
  问题是:每次循环计算的某些列的值是相同的。但自定义函数根据ID每次返回的表是正确的。
  解决方法是:我怀疑是UPDATE时表变量中的数据没变。所以在每次循环时都要清空表变量,问题才得以解决。按程序的特点来说,一个变量从声明开始到它遇到的第一个左大括号结束,可是为
什么下面的问题在第二次循环时值还存在呢?
--------------------------------------
SQL code
 declare @win char(10) 
DECLARE win_cursor CURSOR FOR
SELECT [ID]
FROM sys_CheckOneKm
WHERE CheckID=@runID

OPEN win_cursor

FETCH NEXT
FROM win_cursor into @win
WHILE @@FETCH_STATUS =0
BEGIN

/*-----------------------------
*在此计算ID为@win的千米表的参数
------------------------------*/
---定义数据参数
    declare
    @MQI  decimal(15,7),@PQI  decimal(15,7),@PCI  decimal(15,7),@RQI  decimal(15,7),@RDI  decimal(15,7),@SRI  decimal(15,7),@PSSI  decimal(15,7),@SCI  decimal(15,7),@BCI  decimal(15,7),@TCI  decimal(15,7) ,@Thinkness  decimal(15,7)
--定义存储表
declare @pTable table(
      [ID] [smallint] IDENTITY (1, 1) NOT NULL ,
    --  MQI    decimal(15,7),
    --  PQI    decimal(15,7),
    -- PCI    decimal(15,7),
      RQI    decimal(15,7),
      RDI    decimal(15,7),
      SRI    decimal(15,7),
      PSSI    decimal(15,7),
      WiAi    decimal(15,7),
      Ai    decimal(15,7),
      Thinkness    decimal(15,7)

    )
delete @pTable
--调用运算千米函数
select * from  @pTable --测试查看每一千米返回的基本数据
INSERT INTO @pTable(RQI ,RDI,SRI,PSSI,WiAi,Ai,Thinkness) SELECT RQI ,RDI,SRI,PSSI,WiAi,Ai,Thinkness FROM dbo.[retTabel](@win)

--select * from  @pTable --测试查看每一千米返回的基本数据
print @win  --测试打印出循环获得的千米ID

SET @PCI= dbo.[retPCI](@win,(SELECT SUM(CAST([WiAi] as  decimal(15,7))) FROM @pTable))
SET @RQI=(SELECT AVG(CAST([RQI] as  decimal(15,7))) FROM @pTable)
SET @RDI=(SELECT AVG(CAST([RDI] as  decimal(15,7))) FROM @pTable)
SET @SRI=(SELECT AVG(CAST([SRI] as  decimal(15,7))) FROM @pTable)
SET @PSSI=(SELECT AVG(CAST([PSSI] as  decimal(15,7))) FROM @pTable)
SET @Thinkness=(SELECT AVG(CAST([Thinkness] as  decimal(15,7))) FROM @pTable)

SET @PQI=dbo.[retPQI] (@PCI,@RQI,@RDI, @SRI)
--SET @SCI=(SELECT AVG(CAST([SCI] as  decimal(15,7))) FROM dbo.[retTabel](@win))
--SET @BCI=(SELECT AVG(CAST([BCI] as  decimal(15,7))) FROM dbo.[retTabel](@win))
--SET @TCI=(SELECT AVG(CAST([TCI] as  decimal(15,7))) FROM dbo.[retTabel](@win))
--SET @MQI=(SELECT AVG(CAST([MQI] as  decimal(15,7))) FROM dbo.[retTabel](@win))


--更新千米参数值
UPDATE sys_CheckOneKm  SET MQI=@MQI,PQI=@PQI,PCI=@PCI,RQI=@RQI,RDI=@RDI,SRI=@SRI,PSSI=@PSSI,SCI=@SCI,BCI=@BCI,TCI=@TCI
  ,Thinkness=@Thinkness WHERE ID=@win

FETCH NEXT FROM win_cursor into @win
End
  close win_cursor  --关闭游标
    deallocate win_cursor

END

GO



------解决方案--------------------
变量在你的这个过程里是一直存在的,除非这个过程结束,或你人为进行处理。
------解决方案--------------------
1、这样更合理吧

declare cur cursor for ...
open cur
declare @t table(....)
fetch cur ...
while @@fetch_status ...
begin
delete from @t.