定义局部游标就可以解决递归中的游标已经存在的问题declare 游标名cursor local --local关键字指定游标是局部游标
for 
select ...

解决方案 »

  1.   

    --楼主的问题说得不清楚,具体 info 要怎么改并没有说明,循环查询的目的是什么,也没有说明--实现部分功能的示例
    create proc 示例
    @info varchar(10),
    @newkey int output
    as--将A表中满足条件的记录查出来,能否存储在一临时变量中--定义保存查询结果的表变量
    declare @表变量 table(a_key int,b_info varchar(10))--查询结果存入表变量
    insert @表变量 select a_key,b_info from A表 where 条件
    --然后在刚才的查询结果中对每一条记录循环,
    --将 info 按程序需要修改后重新加入A表中(调用前面已有的那个存储过程)--如果是实现这个目的,就没有必要用变量保存查询结果,而是直接用游标--定义游标
    declare tb cursor local for
    select a_key,b_info from A表 where 条件--定义得到当前记录值的变量
    declare @a_key int,@b_info varchar(10)--打开游标
    open tb--循环取数
    fetch next from tb into @a_key,@b_info
    while @@fetch_status=0
    begin
    ---进行处理
    fetch next from tb into @a_key,@b_info
    end--处理完成后关闭游标
    close tb
    deallocate tb
      

  2.   

    需要递归调用自身的原因:在表结构中的 a_info 其实是多个数据字段
    A表为一个树形结构表,a_info 中即有一个字段保存父节点信息
    现贴出部分数据
    (ps: "" 代表长度为零的字符串)
    资料ID    父路径                信息字段
    Z0001     ""                    根节点
    Z0002     \Z0001                根节点的第一子节点
    Z0003     \Z0001\Z0002          Z0002的第一子节点
    Z0004     \Z0001\Z0002\Z0003    Z0003的第一子节点
    Z0005     \Z0001\Z0002          Z0002的第二子节点
    Z0006     \Z0001                根节点的第二子节点
      

  3.   

    呵呵,果然不愧是  邹键!!
    程序写好了,测试后没有问题
    关键就是按邹键说的将游标定义为局部变量即可解决在递归调用中的冲突问题
    现将代码附在后面供与我一样的菜花同志们学习
    谢谢大家关注
    CREATE PROCEDURE proc_MRP_product_stru_copy
    @theNode NVARCHAR(20), @newParentNode NVARCHAR(20), @includeParent NVARCHAR(3)
    AS
    DECLARE @oldRootPath NVARCHAR(255), @newRootPath NVARCHAR(255)
    DECLARE @theID NVARCHAR(20), @theParent NVARCHAR(255), @theNo NVARCHAR(20), @theName NVARCHAR(50), @theAmount INT
    DECLARE @productParent NVARCHAR(20), @productSerialno SMALLINT, @productCode NVARCHAR(20), @productAmount FLOAT
    DECLARE @returnID NVARCHAR(20)
    DECLARE @newRootNode NVARCHAR(20)SELECT @oldRootPath = 父资料key FROM MRP_产品配置结构表 WHERE 资料ID = @theNode
    SET @oldRootPath = @oldRootPath +'\' + @theNode
    SET @newRootNode = @newParentNode
    SELECT @newRootPath = 父资料key FROM MRP_产品配置结构表 WHERE 资料ID = @newParentNode
    SET @newRootPath = @newRootPath + '\' + @newParentNode--  此处 @includeParent 传过来的值应只有两种      'yes'    or    'no'
    IF @includeParent = 'yes' -- 先处理当前节点及其物料清单
    BEGIN
    DECLARE nodeCursor  SCROLL CURSOR FOR
    SELECT 资料ID, 父资料key, 产品编号, 产品名称, 引用数量 FROM MRP_产品配置结构表
    WHERE 资料ID = @theNode 
    -- ORDER BY 父资料key, 资料ID OPEN nodeCursor
    FETCH NEXT FROM nodeCursor INTO  @theID, @theParent, @theNo, @theName, @theAmount
    IF @@FETCH_STATUS = 0
    BEGIN
    --  处理过程  开始     >>>>>>>>>>>>>>>>>>>
    EXECUTE proc_MRP_product_stru_add @newRootNode, @theNo, @theName, @theAmount, @returnID OUTPUT DECLARE productCursor SCROLL CURSOR FOR
    SELECT 父资料key, 序号, 物品编码, 数量 FROM MRP_产品配置明细表
    WHERE 父资料key = @theID

    OPEN productCursor
    FETCH FIRST FROM productCursor INTO @productParent, @productSerialno, @productCode, @productAmount
    WHILE @@FETCH_STATUS = 0
    BEGIN
    --  循环将 物料清单 拷贝到新节点下 开始     >>>>>>>>>>>>>>>>>>>
    INSERT INTO MRP_产品配置明细表
    (父资料key, 序号, 物品编码, 数量)
    VALUES (@returnID, @productSerialno, @productCode, @productAmount)
    --  循环将 物料清单 拷贝到新节点下  结束    <<<<<<<<<<<<<<<<<<<
    FETCH NEXT FROM productCursor INTO @productParent, @productSerialno, @productCode, @productAmount
    END
    CLOSE productCursor
    DEALLOCATE productCursor
    --  处理过程  结束    <<<<<<<<<<<<<<<<<<<

    SET @newRootNode = @returnID
    SET @newRootPath = @newRootPath + '\' + @returnID
    -- FETCH NEXT FROM nodeCursor INTO  @theID, @theParent, @theNo, @theName, @theAmount 
    END
    ELSE -- 如 @@FETCH_STATUS <> 0 说明当前节点出错了,因此后面程序段不执行
    BEGIN
    RETURN
    CLOSE nodeCursor
    DEALLOCATE nodeCursor
    END CLOSE nodeCursor
    DEALLOCATE nodeCursor
    END
    BEGIN
    DECLARE nodeCursor CURSOR LOCAL FOR
    SELECT 资料ID, 父资料key, 产品编号, 产品名称, 引用数量 FROM MRP_产品配置结构表
    WHERE 父资料key = @oldRootPath 
    ORDER BY 父资料key, 资料ID OPEN nodeCursor
    FETCH NEXT FROM nodeCursor INTO  @theID, @theParent, @theNo, @theName, @theAmount
    WHILE @@FETCH_STATUS = 0
    BEGIN
    --  处理过程  开始     >>>>>>>>>>>>>>>>>>>
    EXECUTE  proc_MRP_product_stru_copy @theID, @newRootNode, 'yes'  --   @theNode NVARCHAR(20), @newParentNode NVARCHAR(20), @includeParent NVARCHAR(3)
    /* EXECUTE proc_MRP_product_stru_add @newRootNode, @theNo, @theName, @theAmount, @returnID OUTPUT DECLARE productCursor SCROLL CURSOR FOR
    SELECT 父资料key, 序号, 物品编码, 数量 FROM MRP_产品配置明细表
    WHERE 父资料key = @theID

    OPEN productCursor
    FETCH FIRST FROM productCursor INTO @productParent, @productSerialno, @productCode, @productAmount
    WHILE @@FETCH_STATUS = 0
    BEGIN
    --  循环将 物料清单 拷贝到新节点下 开始     >>>>>>>>>>>>>>>>>>>
    INSERT INTO MRP_产品配置明细表
    (父资料key, 序号, 物品编码, 数量)
    VALUES (@returnID, @productSerialno, @productCode, @productAmount)
    --  循环将 物料清单 拷贝到新节点下  结束    <<<<<<<<<<<<<<<<<<<
    FETCH NEXT FROM productCursor INTO @productParent, @productSerialno, @productCode, @productAmount
    END
    CLOSE productCursor
    DEALLOCATE productCursor
    */
    --  处理过程  结束    <<<<<<<<<<<<<<<<<<<

    FETCH NEXT FROM nodeCursor INTO  @theID, @theParent, @theNo, @theName, @theAmount 
    END
    CLOSE nodeCursor
    DEALLOCATE nodeCursor
    END
    GO
      

  4.   

    因此站输入框行的长度问题有些过长的代码转行了引起代码阅读可能有问题
    建议大家如果要看 copy 到开发语言中阅读起来会方便点此贴问题已处理好,供朋友们学习后下午结贴
    至本贴关所有关注的朋友都有分谢谢