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

--数据源递归取值代码生成
--sys_sql_get_val @cmpid,@parseid,@pretbname,@preBank,@isRecursive,@forceget@inCursorDS@hasUpDS@script 
create procedure [dbo].[sys_sql_get_val] (
@cmpid int,
@parseid int,
@pretbname varchar(20),
@preBank varchar(50),
@isRecursive int ,--是否递归调用
@forceget int,       --是否强制明细表取值， 1=强制取值  0=明细表停止取值
@inCursorDS varchar(20),  --所在游标DS
@hasUpDS int output,--是否有上级
@script nvarchar(max) output
)
as 
begin

--变量定义
declare     @dsname varchar(20),@i int,@tbname varchar(20),@prebank2 varchar(20),@varType varchar(10),@predschain varchar(50)
,@varName varchar(20),@fromInd int ,@toInd int, @dschain varchar(50),@hasUpDSs int, @predsname varchar(20),@script2 varchar(max)
,@keyval varchar(20),@preLnkFld varchar(20),@biztype varchar(20),@prekeyval varchar(20),@isDetailTable int,@tagid int
  ,@keyfld varchar(20),@prekeyfld varchar(20),@shortname varchar(20),@bizid int,@preLnkVal varchar(20),@fullName varchar(100)
  ,@predsbiztype varchar(20),@predsbizid int,@predstagid int,@idParamVar varchar(20),@isLoaded int,@sqlCond varchar(200)
  ,@isExistUpper int,@biztypeUpper varchar(10),@bizidUpper int,@tagidUper int
--关键变量初始化
select @i=0,@hasUpDS = 0 ,@script=''
select @prebank2=@preBank + '  '

--1 前数据源类型信息 begin
if (@pretbname is not  null)
select @predsbiztype=biztype,@predsbizid = bizid,@predstagid=tagid,@predsname=predsname
from flatDSS
where tbname=@pretbname and parseid=@parseid
else
select @predsbiztype=null,@predsbizid = null,@predstagid=null,@predsname=null

set @predschain='NULL'

if (@pretbname is not null)
select @predschain = dschain 
from flatDSS
where tbname=@predsname and parseid=@parseid
--辅助调试信息
select @script = @preBank + ' --  in gettable  pre dschain: ' + @predschain + char(13)

--上级，但是上级表中无记录，通过特殊的方式，设置pretbname
if (@pretbname is not null)
begin
  select @predsname=dsname from flatDSS where tbname=@pretbname
  update flatDSS
  set pretbname=@pretbname
  where parseid=@parseid and predsname=@predsname and biztype='BIZ' and bizid=-1
end


--2.生成该数据源名称下的所有物理表记录游标： tbCursor
if (@pretbname is not null)
Declare  tbCursor Cursor local static For
select tbname,keyval,preLnkFld,pretbname,prekeyfld,shortname,keyfld,bizid,biztype,dsname,
fullname,predsname,isDetailTable,tagid,idParamVar,isLoaded,sqlCond
from flatDSS
where parseid=@parseid and pretbname=@pretbname
else
Declare  tbCursor Cursor local static For
select tbname,keyval,preLnkFld,pretbname,prekeyfld,shortname,keyfld,bizid,biztype,dsname,
fullname,predsname,isDetailTable,tagid,idParamVar,isLoaded,sqlCond
from flatDSS
where parseid=@parseid and pretbname is null


Open tbCursor
Fetch Next From tbCursor Into @tbname ,@keyval,@preLnkFld ,@pretbname,@prekeyfld,@shortname,@keyfld,@bizid,
@biztype,@dsname,@fullName,@predsname,@isDetailTable,@tagid,@idParamVar,@isLoaded,@sqlCond
declare @upcount int
set @upcount = 0

--3 游标循环
while  (@@FETCH_STATUS=0)
begin --  3 游标循环
if (@tbname is null)
print 'error:'+ @dsname + ' 没有对应的table '  

--当前表类型信息
select @script=@script + char(13) + 
@preBank +' select @curbiztype__='''+ @biztype+''',@curbizid__=' + convert(varchar(10),@bizid) +
',@curtagid__='+convert(varchar(10),@tagid) + char(13)

--1）普通数据源
if (@shortname != '上级' and @shortname !='根' and @isDetailTable=0)
begin--1）普通数据源
  --如果指定了参数，用指定参数替换
 if (@idParamVar is not null and len(@idParamVar)>1)
select @script=@script + char(13) + 
@preBank +' select @'+@dsname+'_keyval__=' + @idParamVar +  char(13)

--数据加载
--一般情况下，数据不重复加载
if (@forceget=1 or @isLoaded=0)
exec sys_sql_getfldval @cmpid,@parseid,@dsname,@tbname,@keyfld,@preBank,@script2 output
if (@script2 is not null)
select @script=@script +@script2

--递归后级 如果存在后级，递归后级:如果有后级是'上级'，'上级'表又没记录，不会生成
select @i=count(*) from flatDSS where pretbname=@tbname and parseid=@parseid
if (@i=0) -- 解决后级是'上级'，单上级表中无记录的情况
select @i=count(*) from flatDSS where predsname=@dsname and parseid=@parseid

if (@i>0)
begin
select @script = @script + @preBank +' -- 保存前级表类型信息 -- '+  char(13) +
@preBank +' select @prebiztype__=@curbiztype__,@prebizid__=@curbizid__,@pretagid__=@curtagid__' +
',@preordid__=@curordid__,@preord2id__=@curord2id__'+  char(13)
select @preBank = @preBank + '  '
exec sys_sql_get_val @cmpid,@parseid,@tbname,@preBank,1,@forceget,@inCursorDS,@hasUpDS output, @script2 output

-- 合并后级脚本
if (@script2 is not null and len(@script2)>0)
select @script = @script + char(13) + @script2 
end
select @script = @script + char(13) +
@preBank +' -- 数据源取值结束： ' + @fullname + char(13)

end      --end 非上级 1
-- 2)上级，根
  else if (@shortname='上级' or @shortname='根')   
begin   -- 2)

--  上级通用部分
if (@upcount=0)
begin     --通用部分
select @hasUpDS=1  --存在上级

--2.3.2.2 设置“数据源未出现”标志
select @script = @script + char(13)+
@preBank + ' -- 上级 BEGIN  -- ' + @fullname + char(13) +     
@preBank + ' -- 设置上级业务类型不存在 -- ' + char(13) +     
@preBank + 'select @sys_sql_isUpBizExisted__=0,@hasUpDS__=1 ' + char(13)

--2.3.2.3 从前级表（pretbname）中获得本级记录ID，BIZTYPE, BIZID。
declare @isdetailPre int
select @isdetailPre=isdetailtable 
from flatDSS
where dsname=@predsname

if (@shortname='上级' and @isdetailPre=0 ) --上级是主表
select @script=@script + char(13) + 
@preBank +'   --获得数据源信息：上级 业务类型，连接值' + char(13)+
@preBank +' select @' + @dsname + '_biztype__=@'+@predsname +'_fbiztype ' +
' ,@' + @dsname + '_bizid__=@'+@predsname +'_fbizid__' + 
' ,@' + @dsname + '_tagid__=@'+@predsname +'_ford2tag__' + 
' ,@' + @dsname + '_prelnkval__=@'+@predsname + '_fordid__'+ 
' ,@'+@dsname + '_keyval__=@' + @predsname + '_fordid__' + char(13)

if (@shortname='上级' and @isdetailPre=01 ) --上级是明细表
select @script=@script + char(13) + 
@preBank +'   --获得数据源信息：上级 业务类型，连接值' + char(13)+
@preBank +' select @' + @dsname + '_biztype__=@'+@predsname +'_fbiztype__ ' +
' ,@' + @dsname + '_bizid__=@'+@predsname +'_fbizid__' + 
' ,@' + @dsname + '_tagid__=@'+@predsname +'_ford2tag__' + 
' ,@' + @dsname + '_prelnkval__=@'+@predsname + '_ford2id__'+ 
' ,@'+@dsname + '_keyval__=@' + @predsname + '_ford2id__' + char(13)

if (@shortname='根'  and @isdetailPre=0 )
select @script=@script + char(13) + 
@preBank +'   --获得数据源信息：上级 业务类型，连接值' + char(13)+
@preBank +' select @' + @dsname + '_biztype__=@'+@predsname +'_rbiztype__ ' +
' ,@' + @dsname + '_bizid__=@'+@predsname +'_rbizid__' +
' ,@' + @dsname + '_tagid__=@'+@predsname +'_rord2tag__' + 
' ,@' + @dsname + '_prelnkval__=@'+@predsname + '_rordid__'+ 
' ,@'+@dsname + '_keyval__=@' + @predsname + '_rordid__' + char(13)
if (@shortname='根'  and @isdetailPre=1 )
select @script=@script + char(13) + 
@preBank +'   --获得数据源信息：上级 业务类型，连接值' + char(13)+
@preBank +' select @' + @dsname + '_biztype__=@'+@predsname +'_rbiztype__ ' +
' ,@' + @dsname + '_bizid__=@'+@predsname +'_rbizid__' +
' ,@' + @dsname + '_tagid__=@'+@predsname +'_rord2tag__' + 
' ,@' + @dsname + '_prelnkval__=@'+@predsname + '_rord2id__'+ 
' ,@'+@dsname + '_keyval__=@' + @predsname + '_rord2id__' + char(13)
end -- 通用部分

-- 对每种上级分别处理：循环，处理上级实例
select @script=@script + char(13) + 
@preBank +'   -- while : ' + @fullname + char(13) 
if (@upcount>0)
select @script=@script + 'else ' 

--（a）生成动态值与静态值比较分支语句script
if (@bizid>0)
begin   -- 上级 1.3  ： 生成上级的每种实例代码
  select @script=@script +  
@preBank +'if ((@'+@dsname +'_bizid__=' + convert(varchar(4), @bizid)+')' + 
 ' and (@'+@dsname +'_tagid__=' + convert(varchar(4), @tagid)+'))' + char(13) + 
@preBank +'begin       -- '  +@dsname +'_bizid=' + convert(varchar(4), @bizid)+')' +  char(13) +
@preBank +'  select @sys_sql_isUpBizExisted__=1 ' + char(13) +  --（b）清除“数据源未出现”标志script
@preBank +  char(13) +
@preBank +'  --获得本级表字段数据，包括记录ID   ' +  char(13) 

  --（c）取数据源字段值script
if (@isLoaded = 1)  --不重复取数
goto nxt
  
  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  

  select @script=@script + @preBank +' -- end 本级数据获取 ' + char(13) 

  select @upcount=@upcount + 1


 --(d)递归后级 如果存在后级，递归后级
if (@tbname is not null)  --防止出现死循环，加条件
begin-- --(d)递归后级 
declare @nextDSShort varchar(20)
select @nextDSShort=shortname
from flatDSS
where parseid=@parseid and pretbname=@tbname

if (@nextDSShort is not null)
begin   --上级1.3.1.1 

select @script=@script + char(13) +
@preBank +' -- 递归下级 ' + @fullname + ': ' + @tbname + char(13) 
if (@nextDSShort='上级')
select @script=@script + char(13) +
@preBank +'  select @sys_sql_isUpBizExisted__=0 --nextDSShort' + @nextDSShort+ char(13) 

select @preBank = @preBank + '  '
exec sys_sql_get_val @cmpid,@parseid,@tbname,@preBank,1,@forceget,@inCursorDS,@hasUpDS output, @script2 output

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


select @script=@script + 
@preBank +'end  --  ' + @dsname +'_bizid=' + convert(varchar(4), @bizid)+')' + char(13)
end  -- if (@bizid>0) 

select @script = @script +  
@preBank +' -- 上级 end : ' + @fullname + char(13)

end  -- 2)上级、根
--3)明细表
  else if (@isDetailTable=1)
  goto nxt;

nxt:
--置取数标志
update flatDSS
set isLoaded = 1
where parseid=@parseid and tbname = @tbname

Fetch Next From tbCursor Into @tbname ,@keyval,@preLnkFld ,@pretbname,@prekeyfld,@shortname,@keyfld,@bizid,@biztype,
@dsname,@fullName,@predsname,@isDetailTable,@tagid,@idParamVar,@isLoaded,@sqlCond
end -- end tbcursor

if (@shortname='上级' or @shortname='根')
begin

select @script = @script +  
@preBank +' -- 判断上级是否程序化  -- ' +char(13) +
@preBank +'if (@sys_sql_isUpBizExisted__=0)' + char(13) +
@preBank +'begin' + char(13) +
@preBank +' -- 加入上级记录' + char(13) +
 @preBank + '  exec sys_sql_addUptable @cmpid,@prebiztype__ ,@prebizid__ ,@pretagid__,@preordid__,@preord2id__' + char(13)
 
-- 先释放游标资源
declare @csname varchar(20)
Declare incs Cursor For
select cursorname from flatCursor
order by cursorid
open incs
Fetch next from incs into @csname
while (@@Fetch_status=0)
begin
select @script = @script + 
@preBank + '  Close ' + @csname + char(13) +
@preBank +'  Deallocate ' + @csname +char(13)
Fetch next from incs into @csname
end
close incs
deallocate incs
 
select @script = @script +  
@preBank +'goto regenscript ' + char(13) +
@preBank +'end' + char(13) 
end

Close tbCursor
Deallocate tbCursor


over1:
set @i=0

END