IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID('[dbo].[sys_sql_cmd_upin]') AND type = 'P')
DROP PROCEDURE [dbo].[sys_sql_cmd_upin]
GO

-- exec sys_sql_cmd_upin @cmpid,@parseid,@targetDS,@targetTb,@preBank,@loadedGetOrder,@opTyp,@script  output

--生成update,insert 脚本
create procedure [dbo].[sys_sql_cmd_upin] (
@cmpid int, 
@parseid int,
@targetDSvarchar(20), --目标数据源名称
@targetTb varchar(20),      --目标物理表名
@preBank varchar(20),
@loadedGetOrder int,        --已经取数数据源序号
@opTyp varchar(10),
@script nvarchar(max) output
)
as
begin
set @script = ''
declare @dsname varchar(20),@tbname varchar(20),@biztype varchar(20),@keyfld varchar(20),@script2 varchar(max),@cscript varchar(max)
,@preBank2 varchar(50),@hasPostDS int,@hasUpDS int,@fullName varchar(50),@flds varchar(2000),@fldvars varchar(2000),@fldvals varchar(2000)
,@bizid int,@tagid int,@isupper int,@isroot int,@isdetailtable int,@getOrder int,@upcount int,@lastCall int,@shortname varchar(20)
,@predsname varchar(20),@maxGetOrder int,@nextRecursiveOrder int,@mxOrder int, @hasSubRecursive int
,@pretbname varchar(20),@prebizid int,@pretagid int,@prekeyfld varchar(20)
,@preIsroot int,@preIsUpper int, @csname varchar(20),@i int,@isLoaded int,@nodata int
,@tbdatabase varchar(30)

--最大取数顺序
  select @mxorder=max(getOrder)
  from flatDSS
  where parseid=@parseid 
  
--下一个递归点
select top 1 @nextRecursiveOrder = getOrder
from flatDSS
where parseid=@parseid and getorder>@loadedGetOrder and (isupper=1 or isroot=1 or isdetailTable=1)
order by getorder

  if (@nextRecursiveOrder is null) 
  set @nextRecursiveOrder=@mxorder

--最后一层调用
--@hasSubRecursive 是否有下级递归调用
select  @lastCall = 1,@maxGetOrder=@loadedGetOrder,@hasSubRecursive=0  

--
--1 待取数据源
Create table #tbds(dsname varchar(20),getorder int)
insert into #tbds(dsname)
 select distinct dsname
  from flatDSS
  where parseid=@parseid and getOrder>@loadedGetOrder and getorder <=@nextRecursiveOrder and isloaded=0
update #tbds
set #tbds.getorder=flatDSS.getorder 
from flatDSS where #tbds.dsname=flatDSS.dsname

Declare dsLogic cursor static local For
  select dsname
  from #tbds
  order by getorder

set @nodata=1
--2 顺序取数据
open dsLogic
fetch next from dsLogic into @dsname
while (@@fetch_status=0)
begin
select @preIsroot=0 ,@preIsUpper =0

--2.1当前逻辑数据源下的物理数据源
declare dsPhy cursor local static for
select tbname,biztype,bizid,tagid,isupper,isroot,isdetailtable,keyfld,getorder,shortname,predsname,fullname,pretbname,isLoaded,tbdatabase
  from flatDSS
  where parseid=@parseid and dsname=@dsname and getOrder<=@nextRecursiveOrder and isloaded=0 
Open dsPhy

set @upcount=0  --如果是上级或根，这个参数将发生作用

fetch next from dsPhy into @tbname,@biztype,@bizid,@tagid,@isupper,@isroot,@isdetailtable,@keyfld,
        @getorder,@shortname,@predsname,@fullname,@pretbname,@isLoaded,@tbdatabase
set @nodata=0
select @preIsroot=@isroot ,@preIsUpper =@isupper
select @script = @script + 
@preBank + 'select @curbiztype__=''' +@biztype +''',@curbizid__=' + convert(varchar(10),@bizid) + 
      ',@curtagid__=' + convert(varchar(10),@tagid) + char(13) 
--前级信息
select @prebizid = bizid,@pretagid =tagid,@prekeyfld=keyfld
from flatDSS where tbname=@pretbname 

while (@@fetch_status=0)
begin
if (@tbdatabase is null)
set @tbdatabase = ''
--不同的数据源类型，处理方法不同
select @maxGetOrder = @getOrder
if (@fullname is null)
set @fullname=''
if (@dsname = @targetDS)
set @targetTb=@tbname

--2.1.1 普通数据源，直接取数 **********************************************************************************************
if(@isupper=0 and @isroot=0 and @isdetailtable=0 and @isLoaded=0)
begin
exec sys_sql_getfldval @cmpid,@parseid,@dsname,@tbname,@keyfld,@preBank,@script2 output
if (@script2 is not null)
select @script = @script + char(13) + @script2
end

--2.1.2 上级或根 ***********************************************************************************************************
if (@isupper=1 or @isroot=1)
begin
--2.1.2.1  上级通用部分
if (@upcount=0)  
begin     
select @hasUpDS=1  --存在上级 ,@curordid,@curord2id
select @script = @script + char(13)+
@preBank + ' -- 上级 BEGIN  -- ' + @fullname + char(13) +     
@preBank + ' -- 设置上级业务类型不存在 -- ' + char(13) +     
@preBank + 'select @sys_sql_isUpBizExisted__=0,@hasUpDS__=1,@gotogen__=0,@curordid__=0,@curord2id__=0 ' + char(13)
end 

--2.1.2.2 代码化已知每种上级（根）
if (@upcount>0) 
select @script=@script + 'else ' 
if (@isupper=1 and @pretagid=0) --上级，前级为主表
select @script=@script +  
@preBank +'if ((@'+@pretbname +'_ord_fbizid__=' + convert(varchar(4), @bizid)+')' + 
 ' and (@'+@pretbname +'_ord_ford2tag__=' + convert(varchar(4), @tagid)+'))' + char(13)+
@preBank +'begin ' + CHAR(13) +
@preBank +'  if (@'+@pretbname+'_ord_fordid__>0) ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+'__=@' + @pretbname+'_ord_fordid__'  +  char(13)+
@preBank +'  else ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+ '__=@' + @pretbname+'_ord_ford2id__'  +  char(13)

if (@isupper=1 and @pretagid=1) --上级，前级为明细表
select @script=@script +  
@preBank +'if ((@'+@pretbname +'_ord2_fbizid__=' + convert(varchar(4), @bizid)+')' + 
 ' and (@'+@pretbname +'_ord2_ford2tag__=' + convert(varchar(4), @tagid)+'))' + char(13)+
@preBank +'begin ' + CHAR(13) +     
@preBank +'  if (@'+@pretbname+'_ord2_fordid__>0) ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+ '__=@' + @pretbname+'_ord2_fordid__'  +  char(13)+
@preBank +'  else ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+ '__=@' + @pretbname+'_ord2_ford2id__'  +  char(13)

if (@isroot=1 and @pretagid=0) --根，前级为主表
select @script=@script +  
@preBank +'if ((@'+@pretbname +'_ord_rbizid__=' + convert(varchar(4), @bizid)+')' + 
 ' and (@'+@pretbname +'_ord_rord2tag__=' + convert(varchar(4), @tagid)+'))' + char(13)+
@preBank +'begin ' + CHAR(13) +     
@preBank +'  if (@'+@pretbname+'_ord_rordid__>0) ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+ '__=@' + @pretbname+'_ord_rordid__'  +  char(13)+
@preBank +'  else ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+ '__=@' + @pretbname+'_ord_rord2id__'  +  char(13)

if (@isroot=1 and @pretagid=1) --根，前级为明细表
select @script=@script +  
@preBank +'if ((@'+@pretbname +'_ord2_rbizid__=' + convert(varchar(4), @bizid)+')' + 
 ' and (@'+@pretbname +'_ord2_rord2tag__=' + convert(varchar(4), @tagid)+'))' + char(13)+
@preBank +'begin ' + CHAR(13) +     
@preBank +'  if (@'+@pretbname+'_ord2_rordid__>0) ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+ '__=@' + @pretbname+'_ord2_rordid__'  +  char(13)+
@preBank +'  else ' + CHAR(13) +     
@preBank +'    select @'+@tbname+'_' + @keyfld+ '__=@' + @pretbname+'_ord2_rord2id__'  +  char(13)
   
select @script=@script +  
@preBank +'  select @sys_sql_isUpBizExisted__=1 ' + char(13) + 
@preBank +'  --获得本级表字段数据，包括记录ID   ' +  char(13)

if (@keyfld='ord_id')
select @script=@script +
@preBank +'set @curordid__=@'+@tbname+'_' + @keyfld  + '__'+ char(13)
if (@keyfld='ord2_id')
select @script=@script + 
'set @curord2id=@'+@tbname+'_' + @keyfld + '__' + char(13) 

-- 取数据
if (@isLoaded=0)
begin
exec sys_sql_getfldval @cmpid,@parseid,@dsname,@tbname,@keyfld,@preBank,@script2 output
-- 合并script
if (@script2 is not null and len(@script2)>1)
 select @script=@script + char(13) + @script2  
end
select @upcount=@upcount + 1

--(递归后级
if (@tbname is not null)  --防止出现死循环，加条件
begin
select @isupper=isupper,@isroot=isroot
from flatDSS
where parseid=@parseid and pretbname=@tbname

select @script=@script + char(13) +
@preBank +' -- 递归下级 ' + @fullname + ': ' + @tbname + char(13) 
if (@isupper=1 or @isroot=1)
select @script=@script + char(13) +
@preBank +'  select @sys_sql_isUpBizExisted__=0 ' 
select @preBank2=@preBank+'  '
 
set @hasSubRecursive =1 
exec sys_sql_cmd_upin @cmpid,@parseid,@targetDS,@targetTb,@preBank2,@GetOrder,@opTyp,@script2  output

--合并后级脚本
if (@script2 is not null and len(@script2)>0)
select @script = @script + char(13) + @script2
end

select @script=@script + 
@preBank +'end  --  ' + @dsname +'_bizid__=' + convert(varchar(4), @bizid)+')' + char(13)
end  -- 2.1.2 上级或根

--2.1.3明细表 **************************************************************************************************************
if (@isdetailTable=1)
begin
--生成游标字段
--@parseid int,@tbname，
--@flds,@fldvars,@fldvals  
update flatDSS
set isLoaded=1
where tbname=@tbname
exec sys_sql_get_flds @parseid,@tbname,0,@flds output,@fldvars output,@fldvals output
 -- 可以完善游标名称命名机制
select @csname='mxcs'+@dsname
insert into flatCursor(cursorname) values(@csname)

select @cscript=@preBank +'  -- 明细表，定义游标 : ' + @shortname + char(13)+
@preBank +' -- ' + char(13) +
@preBank +'DECLARE ' + @csname +' Cursor static For ' + char(13) +
@preBank +'    select ' + @flds + char(13) +
@preBank +'        from ' + @tbdatabase + @tbname + char(13) +
@preBank +'        where ord2_ordid=@' + @pretbname + '_' + @prekeyfld + '__' +char(13) +
@preBank +'   --游标操作 ' + char(13) +
@preBank +'OPEN '+@csname  + char(13) +
@preBank +'FETCH NEXT FROM  ' + @csname +' INTO  '+ @fldvars + char(13) +
@preBank +'WHILE (@@FETCH_STATUS=0) ' + char(13) +
@preBank +'BEGIN ' + char(13) 

if (@haspostDS=1)
select @cscript=@cscript + 
@preBank +'    -- '  + char(13) +
@preBank +' -- 保存前级表类型信息 -- '+  char(13) +
@preBank +'  select @prebiztype__=@curbiztype__,@prebizid__=@curbizid__,@pretagid__=@curtagid__' +
',@preordid__=@curordid__,@preord2id__=@curord2id__'+  char(13)

--后继数据源取数
select @preBank2=@preBank+'  '
set @hasSubRecursive =1 
exec sys_sql_cmd_upin @cmpid,@parseid,@targetDS,@targetTb, @preBank2,@GetOrder,@opTyp,@script2  output

--合并后级脚本
if (@script2 is not null and len(@script2)>0)
select @cscript = @cscript + char(13) + @script2

select @cscript=@cscript + char(13) +
@preBank +'    FETCH NEXT FROM  '+@csname+' INTO  ' + @fldvars + char(13) +
@preBank +'END ' + char(13) +
@preBank +'lbl_' + @csname +':' +  char(13) +
@preBank +'Close ' + @csname +  char(13) +
@preBank +'Deallocate '+ @csname +  char(13) +
@preBank +'if (@gotogen__=1) '+ char(13) 

delete flatCursor where  cursorname=@csname
set @csname=null 
 select top 1 @csname=cursorname
from flatCursor
order by cursorID DESC 
if (@csname is not null)
begin

select @cscript = @cscript +
@preBank + '  goto lbl_' + @csname   +char(13) 
end
else
 select @cscript = @cscript +
@preBank + '  goto lblEnd '  +char(13) 

select @script = @script + @cscript

end --2.1.3明细表

fetch next from dsPhy into @tbname,@biztype,@bizid,@tagid,@isupper,@isroot,@isdetailtable,@keyfld,
             @getorder,@shortname,@predsname,@fullname,@pretbname,@isLoaded,@tbdatabase
end
Close dsPhy
Deallocate dsPhy

 --delete flatCursor where cursorname =@csname

if (@preisupper=1 or @preisroot=1)
begin

select top 1 @csname=cursorname
from flatCursor 
order by cursorID DESC
--可能情况：上级表中还没数据，就不存在else,应直接从新生成存储过程
if(@upcount>0)
select @script = @script + char(13) +
@preBank + 'else  begin ' + char(13) 

select @script = @script + 
@preBank + '  --更新上级 ' + char(13) +
@preBank + '  exec sys_sql_addUptable @cmpid,@curbiztype__,@curbizid__,@curtagid__,@curordid__,@curord2id__ ' + char(13)
if (@csname is not null)
begin
select @script = @script +  
@preBank + '  set @gotogen__=1 ' + char(13) +
@preBank + '  goto lbl_' + @csname   +char(13) 
  --delete flatCursor where  cursorname=@csname
end
else
begin
 select @script = @script +
@preBank + '  goto lblEnd '  +char(13) 
end
if(@upcount>0)
select @script = @script +
@preBank +'end ' + char(13)
end

fetch next from dsLogic into @dsname
end
close dsLogic
Deallocate dsLogic
  
  --3 生成数据操纵代码  
if ((@maxGetOrder=@mxorder or @nodata=1)and @hasSubRecursive=0)  --只有数据取完，才能生成代码
begin
-- 生成操作语句
if (@opTyp='update')
exec sys_sql_genUpdate @parseid,@targetTb, @preBank, @script2 output
else if (@opTyp='insert')
begin
    if (@targetTb is null)
select top 1 @targetTb=tbname from flatDSS where dsname=@targetDS

  exec sys_sql_genInsert @parseid,@targetTb, @preBank,@script2 output
end


if (@script2 is not null)
select @script = @script + @script2
end  

END