请教前辈insert 语句不能欠套的问题,急...分不够再加...

bleempan 2006-04-27 09:54:10
主要是下面这一句,我去掉下面这句程序是可以正确执行的.
set @chvnSql = @chvnSql + 'insert into ' + @chvTempTableName + ' exec GetSalesManByLevel @intTempID,' + @chvID + ',' + @chvLevel + ',' + @chvCurrentCommentLV + ',' + @chvMaxCommentLV + ',' + @chvShrinkState + ' ' + char(10)

递归调用时系统说
服务器: 消息 8164,级别 16,状态 1,行 28
INSERT EXEC 语句不能嵌套。

郁闷...搞了很久搞不出来...

http://community.csdn.net/Expert/topic/4716/4716931.xml?temp=.5362818
有高手说不要用exec
但是我在递归调用时要声明不同的游标名称,不然系统会说游标已经存在...

不知道哪位前辈帮我看一下,万分感谢,领导已经在吹了...郁闷...





-------------------------------------------------------------------------------------------
--标题:
-- 根据级别参数来得到业务员数据
--说明:
-- 第一级,判断指定级别是否为0和1,是的话就插入
-- 第二级,判断指定级别是否为0和2,是的话就插入
-- ...
--参数:
-- 0 表示获取所有下线
-- 1 表示获取一级下线
-- 2 表示获取二级下线
-- 3 表示获取三级下线
-- 4 表示获取四级下线
-- 5 表示获取五级下线
--返回值:
-- 业务员数据表
-------------------------------------------------------------------------------------------

ALTER procedure GetSalesManByLevel
@intID int, --业务员ID
@intTopManID int, --顶部业务员ID,收缩状态时要计算离职人数。
@intLevel int, --当前要取的级别
@intCurrentCommentLV int, --当前推荐管理级别
@intMaxCommentLV int, --最高推荐管理级别
@intShrinkState int --收缩状态1表示开启0表示关闭

as

declare @chvCursorString varchar(15) --将参数ID转换成字符串存入此变量,游标名称由此变量命名。
declare @chvTempTableName varchar(15) --临时表名,递归的话要创建不同的临时表名。
declare @chvnSql nvarchar(3000) --动态参数语句


set @chvCursorString = 'C' + cast(@intID as varchar) --因为ID为数字,加上A是以英文字母开头为游标命名。
set @chvTempTableName = 'T' + cast(@intID as varchar)



set @chvnSql = 'declare @intTempCash int ' + char(10) --存储临时的金额
set @chvnSql = @chvnSql + 'declare @intTempID int ' + char(10) --临时存储业务员ID
set @chvnSql = @chvnSql + 'set @intTempID = 0 ' + char(10)

--数据表做为输入
set @chvnSql = @chvnSql + 'declare @tblSubordinateOutPut table(intID int,chvnName nvarchar(30),chvnSex nvarchar(1),
chvMobileTel varchar(15),dtmJoinDate datetime,intParentID int,intStateID int) ' + char(10)


--查找下级业务员,把数据存入@tblSubordinate。

set @chvnSql = @chvnSql + 'declare @tblSubordinate table(intID int,chvnName nvarchar(30),chvnSex nvarchar(1),
chvMobileTel varchar(15),dtmJoinDate datetime,intParentID int,intStateID int) ' + char(10)
set @chvnSql = @chvnSql + 'insert into @tblSubordinate select * from dbo.SearchSubordinateByID2(' + cast(@intID as varchar) +') ' + char(10)


----------------------------------------------------------------------------------
--判断intLevel是否为0或者是否等于@intCurrentCommentLV都可以对业务员进行读取
----------------------------------------------------------------------------------
set @chvnSql = @chvnSql + 'declare ' + @chvCursorString + ' cursor scroll for select intID from @tblSubordinate ' + char(10)
set @chvnSql = @chvnSql + 'open ' + @chvCursorString + ' ' + char(10)

set @chvnSql = @chvnSql + 'if( ' + cast(@intLevel as varchar) + '= 0 or ' + cast(@intLevel as varchar) + '=' + cast(@intCurrentCommentLV as varchar) + ') ' + char(10)
set @chvnSql = @chvnSql + 'begin ' + char(10)

set @chvnSql = @chvnSql + 'fetch first from ' + @chvCursorString + ' into @intTempID ' + char(10)
set @chvnSql = @chvnSql + 'while @@fetch_status = 0 ' + char(10)
set @chvnSql = @chvnSql + 'begin ' + char(10)

--如何符合级别条件,这里可以把业务员数据存入指定表中。
set @chvnSql = @chvnSql + 'insert into @tblSubordinateOutPut select intID,chvnName,chvnSex,chvMobileTel,dtmJoinDate,intParentID,intStateID from vSalesManInformation where intID=@intTempID ' + char(10)

set @chvnSql = @chvnSql + 'fetch next from ' + @chvCursorSTring + ' into @intTempID ' + char(10)
set @chvnSql = @chvnSql + 'end ' + char(10)

set @chvnSql = @chvnSql + 'end ' + char(10)


--声明临时变量,因为直接在exec后面转换字符串会出错,要转换后存到变量中,再用变量当参数。
declare @chvID varchar(15)
declare @chvTopManID varchar(15)
declare @chvLevel varchar(1)
declare @chvCurrentCommentLV varchar(1)
declare @chvMaxCommentLV varchar(1)
declare @chvShrinkState varchar(1)

set @chvID = cast(@intID as varchar)
set @chvTopManID = cast(@intTopManID as varchar)
set @chvLevel = cast(@intLevel as varchar)
set @chvMaxCommentLV = cast(@intMaxCommentLV as varchar)
set @chvShrinkState = cast(@intShrinkState as varchar)


--递归调用存储过程,把返回的金额存入临时变量,然后再加到总数里。

if( @intShrinkState = 0 )
begin
--如果级别小于等于5,那么就继续读取下一级的数据
if( @intCurrentCommentLV <= @intMaxCommentLV )
begin
set @intCurrentCommentLV = @intCurrentCommentLV + 1
set @chvCurrentCommentLV= cast(@intCurrentCommentLV as varchar)

----------------------------------------------------------------------------------
--再次重新读取数据,进行递归调用。
----------------------------------------------------------------------------------
set @chvnSql = @chvnSql + 'fetch first from ' + @chvCursorString + ' into @intTempID ' + char(10)
set @chvnSql = @chvnSql + 'while @@fetch_status = 0 ' + char(10)
set @chvnSql = @chvnSql + 'begin ' + char(10)

--创建临时表,存存储过程返回的数据。
set @chvnSql = @chvnSql + 'if object_id(''' + @chvTempTableName + ''') is not null ' + char(10)
set @chvnSql = @chvnSql + 'drop table ' + @chvTempTableName + + char(10) +' else ' + char(10)
set @chvnSql = @chvnSql + 'create table ' + @chvTempTableName + ' (intID int,chvnName nvarchar(30),chvnSex nvarchar(1),
chvMobileTel varchar(15),dtmJoinDate datetime,intParentID int,intStateID int) ' + char(10)

--递归调用存储过程,把返回值先存到临时表中,然后把临时表的数据插入到真正的输出表中。
--set @chvnSql = @chvnSql + 'execute(''insert into #tblTemp exec GetSalesManByLevel @intTempID,' + @chvTopManID + ',' + @chvLevel + ',' + @chvCurrentCommentLV + ',' + @chvMaxCommentLV + ',' + @chvShrinkState + ''') '
set @chvnSql = @chvnSql + 'insert into ' + @chvTempTableName + ' exec GetSalesManByLevel @intTempID,' + @chvID + ',' + @chvLevel + ',' + @chvCurrentCommentLV + ',' + @chvMaxCommentLV + ',' + @chvShrinkState + ' ' + char(10)
--set @chvnSql = @chvnSql + 'insert into #tblTemp select * from @tblSubordinateOutPut '

--把数据存入输出表中
--set @chvnSql = @chvnSql + 'insert into @tblSubordinateOutPut select * from #tblTemp '

--丢弃临时表数据
set @chvnSql = @chvnSql + 'if object_id(''' + @chvTempTableName + ''') is not null ' + char(10)
set @chvnSql = @chvnSql + 'drop table ' + @chvTempTableName + ' ' + char(10)

set @chvnSql = @chvnSql + 'fetch next from ' + @chvCursorString + ' into @intTempID ' + char(10)
set @chvnSql = @chvnSql + 'end ' + char(10)


--关闭游标
set @chvnSql = @chvnSql + 'close ' + @chvCursorString + ' ' + char(10)
set @chvnSql = @chvnSql + 'deallocate ' + @chvCursorString + ' ' + char(10)


set @chvnSql = @chvnSql + 'select * from @tblSubordinateOutPut ' + char(10)
print(@chvnSql)
exec(@chvnSql)

end
end
else
select '0'










...全文
128 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
bleempan 2006-04-28
  • 打赏
  • 举报
回复
问题已经解决了,现在不用动态sql可以实现了.
游标要定义为local类型的递归时同名才不会冲突,默认好像是全局的...

不用存储过程,用函数递归(间接递归).
sql里面函数不能直接调用自己,只能间接调用.
这样递归调用返回的数据就可以直接插入表
使用存储过程递归来取数据会造成insert exec不能嵌套的问题.

然后前台调用存储过程来取数据就可以了.

楼上的朋友的方法应该可行,不过我试不出来.
希望以后有朋友碰到此问题可以找到此信息.
拓狼 2006-04-27
  • 打赏
  • 举报
回复
呵呵,这个问题正好我刚刚解决,请到http://spaces.msn.com/tuolang2006/查看
zierben 2006-04-27
  • 打赏
  • 举报
回复
不过好像是传销的样子啊 这么多级别的下线.....
不要做违法事情噢
zierben 2006-04-27
  • 打赏
  • 举报
回复
用自定义函数或者其它方法不用游标,就不用定义游标名了呗
而且你这样的游标本来就超级慢.就不应该用
冷箫轻笛 2006-04-27
  • 打赏
  • 举报
回复
这么长阿!
你上面那样写insert肯定不可以

你可以说一下你想实现什么?
bleempan 2006-04-27
  • 打赏
  • 举报
回复
我主要是想把存储过程返回的表存入一个临时表里.

然后读取临时表里的数据.

可是调用总是失败...

服务器: 消息 8164,级别 16,状态 1,行 28
INSERT EXEC 语句不能嵌套。

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧