alter  procedure Upd_PerMT
 (@Cid varchar(4),
 @MtdStartYear int,
 @beginmonth int) 
as
declare @MtdCol nvarchar(20),@strSql nvarchar(1000)
declare @strAcctNoBE nvarchar(100)
declare @strAcctName nvarchar(100)
declare @strCriteriaClassify nvarchar(100)
declare @intClassify int
set @beginmonth=4while (@beginmonth<=12)
begin
set @MtdCol = 'mtd'+cast(@MtdStartYear as nvarchar) +  convert(nvarchar,RIGHT(100+@beginmonth,2))
DECLARE perMT_Cursor CURSOR FOR
SELECT AcctNoBE, AcctName, CriteriaClassify, Classify
  FROM  RPT_resultA41_perMT 
  where companyId = @Cid
  order by acctNoBe
OPEN perMT_Cursor
FETCH NEXT FROM perMT_Cursor into 
 @strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify

    IF (@@FETCH_STATUS <> 0)
    BEGIN
BREAK
END 
 set @strSql =  'update d set d.' +  @MtdCol +'= (  
 select  SUM(' +  @MtdCol + ') / ' + 
' (select a.SalesVolume from f_salesvolumeuser a inner join D_FiscalDate b
  on a.FiscalDateID = b.FiscalDateID
  and a.companyid = b.companyid 
  where b.fromdateString =''' + cast(@MtdStartYear as nvarchar) +  convert(nvarchar,RIGHT(100+@beginmonth,2)) + '01'''+ 
' and a.CompanyID ='+LTRIM(@Cid)+'
)
from rpt_resultA41 c
where  c.'+ @strCriteriaClassify +
' and c.CompanyID ='+LTRIM(@Cid)+'
)
from rpt_resultA41 d 
 where d.classify = 0 
and d.CompanyID ='+LTRIM(@Cid)+'
and d.acctnobe ='''+@strAcctNoBE+''''
FETCH NEXT FROM perMT_Cursor into 
 @strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify
print (@strsql)
 exec (@strSql)
  CLOSE perMT_Cursor
DEALLOCATE perMT_Cursor 
   set @beginmonth=@beginmonth+1
end大家看得出from rpt_resultA41 c
where  c.'+ @strCriteriaClassify +
' and c.CompanyID ='+LTRIM(@Cid)+'
)
from rpt_resultA41 d 
 where d.classify = 0 
and d.CompanyID ='+LTRIM(@Cid)+'
and d.acctnobe ='''+@strAcctNoBE+''''
中的where  c.'+ @strCriteriaClassify +和这个and d.acctnobe ='''+@strAcctNoBE+''''没有改变吗?参数是对的,是循环的问题,大家帮忙看看

解决方案 »

  1.   

    http://www.cnblogs.com/Warmsunshine/archive/2011/02/19/1958449.html
    下班了 自己慢慢看
      

  2.   

     @@fetch_status=0 试下 去掉break
      

  3.   

    给你个游标的实例讲解看看你这个感觉游标 
    IF (@@FETCH_STATUS <> 0)
        BEGIN
            BREAK
        END  
    这儿有问题 
      

  4.   

    啊  FETCH NEXT FROM perMT_Cursor into 
         @strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify
    print (@strsql)
     exec (@strSql)走到这里  游标指向下一行  下面的print还执行不啊   对游标理解不深  如果不是往下执行print继续循环游标的话  那肯定取的是最后一个记录了  那@strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify的值在整个while循环里肯定不会变啊  都是取的这个表 RPT_resultA41_perMT 对应返回结果的最后一条记录啊  这样的话  这么循环的没道理。。不知说的对不对
      

  5.   

    提供一个小案例 希望对楼主有帮助。--测试数据准备
        if(object_id('t1') is not null)drop table t1
        CREATE table t1(
        id int identity(1,1) primary key,
        value nvarchar(20)
        )
        go
        --插入测试数据
        insert into t1(value)
        select '值1'union all
        select '值2'union all
        select '值3'union all
        select '值4'
        
        --查看结果集合
        --select * from t1
        if(OBJECT_ID('p_print')is not null) drop procedure p_print
        go
        create procedure p_print
        as
        begin
    declare @value nvarchar(20)--注意这里的变量类型应该与游标中读取出来的字段类型相同
    --创建游标
    declare cur1 cursor for
    select value from t1
    --打开游标
    open cur1
    fetch next from cur1 into @value--这里的@value对应游标每条记录中的字段value的值 
    while(@@FETCH_STATUS = 0)
    begin
    print 'value:'+@value
    fetch next from cur1 into @value 
    end
    --关闭游标
    close cur1
    --释放游标
    DEALLOCATE cur1
    end

    --调用(去注释调用)
    --exec p_print

    /* 执行结果
    value:值1
    value:值2
    value:值3
    value:值4
    */
      

  6.   

    OPEN perMT_Cursor
    FETCH NEXT FROM perMT_Cursor into 
     @strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify
    declare @pid int
    set @pid=1
    while(@pid<=(select COUNT(*)from dbo.RPT_resultA41_perMT))
    begin
        IF (@@FETCH_STATUS <> 0)
        BEGIN
    BREAK
    END 
     
     set @strSql =  'update d set d.' +  @MtdCol +'= (  
     select  SUM(' +  @MtdCol + ') / ' + 
    ' (select a.SalesVolume from f_salesvolumeuser a inner join D_FiscalDate b
      on a.FiscalDateID = b.FiscalDateID
      and a.companyid = b.companyid 
      where b.fromdateString =''' + cast(@MtdStartYear as nvarchar) +  convert(nvarchar,RIGHT(100+@beginmonth,2)) + '01'''+ 
    ' and a.CompanyID ='+LTRIM(@Cid)+'
    )
    from rpt_resultA41 c
    where  c.'+ @strCriteriaClassify +
    ' and c.CompanyID ='+LTRIM(@Cid)+'
    )
    from rpt_resultA41 d 
     where d.classify = 0 
    and d.CompanyID ='+LTRIM(@Cid)+'
    and d.acctnobe ='''+@strAcctNoBE+''''
    FETCH NEXT FROM perMT_Cursor into 
     @strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify
    print (@strsql)
     exec (@strSql)
     end这部分这样写成功了,可是是蒙的,不了解格式什么的,还待学习
      

  7.   


    嗯  这样循环确实就对了  while条件 直接写 while 1=1  就行了  不用一条查询语句  无实际意义
    昨天的这个 @beginmonth  我以为是啥呢  也没啥用的啊
      

  8.   

    你对比一下对的代码  和 昨天的代码  问题就出在我第一次说的那个如何循环的问题上  昨天的是游标每次取的是最后一条记录才执行exec   现在是游标每指向一个记录就执行一条
      

  9.   

    嗯嗯!明白了,昨天是每次循环都回到if (@@fetch_status=0),所以都取第一数.
    那@beginmonth有用,本来有两个循环的,只是我不全放,怕代码长看到大家烦,就放一个了,哈哈
    全文
    CREATE  procedure [dbo].[Upd_PerMT]
     (@Cid varchar(4),
     @MtdStartYear int,
     @beginmonth int) 
    as
    declare @MtdCol nvarchar(20),@strSql nvarchar(1000)
    declare @strAcctNoBE nvarchar(100)
    declare @strAcctName nvarchar(100)
    declare @strCriteriaClassify nvarchar(100)
    declare @intClassify int
    set @beginmonth=4while (@beginmonth<=12)
    begin
    set @MtdCol = 'mtd'+cast(@MtdStartYear as nvarchar) +  convert(nvarchar,RIGHT(100+@beginmonth,2))
    DECLARE perMT_Cursor CURSOR FOR
    SELECT AcctNoBE, AcctName, CriteriaClassify, Classify
      FROM  RPT_resultA41_perMT 
      where companyId = @Cid
      order by acctNoBe
    OPEN perMT_Cursor
    FETCH NEXT FROM perMT_Cursor into 
     @strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify
    declare @pid int
    set @pid=1
    while(@pid<=(select COUNT(*)from dbo.RPT_resultA41_perMT))
    begin
        IF (@@FETCH_STATUS <> 0)
        BEGIN
    BREAK
    END 
     
     set @strSql =  'update d set d.' +  @MtdCol +'= (  
     select  SUM(' +  @MtdCol + ') / ' + 
    ' (select a.SalesVolume from f_salesvolumeuser a inner join D_FiscalDate b
      on a.FiscalDateID = b.FiscalDateID
      and a.companyid = b.companyid 
      where b.fromdateString =''' + cast(@MtdStartYear as nvarchar) +  convert(nvarchar,RIGHT(100+@beginmonth,2)) + '01'''+ 
    ' and a.CompanyID ='+LTRIM(@Cid)+'
    )
    from rpt_resultA41 c
    where  c.'+ @strCriteriaClassify +
    ' and c.CompanyID ='+LTRIM(@Cid)+'
    )
    from rpt_resultA41 d 
     where d.classify = 0 
    and d.CompanyID ='+LTRIM(@Cid)+'
    and d.acctnobe ='''+@strAcctNoBE+''''
    FETCH NEXT FROM perMT_Cursor into 
     @strAcctNoBE, @strAcctName, @strCriteriaClassify, @intClassify
    print (@strsql)
     exec (@strSql)
     end
      CLOSE perMT_Cursor
    DEALLOCATE perMT_Cursor 
       set @beginmonth=@beginmonth+1
    end
    GO谢谢您啦