IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID('[dbo].[Sys_sql_expandDs]') AND type = 'P')
DROP PROCEDURE [dbo].[Sys_sql_expandDs]
GO
-- 约定如果数据源中有 this，那么this 的 biztype，bizid已经有值
create procedure [dbo].[Sys_sql_expandDs](
@parseid int,
@cmpid int,
@errmsg varchar(2000) output
)
as
begin

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
select @errmsg=''
--本数据源信息变量
declare @dealCnt int    --记录处理计数器
declare @dsid int,@dsname varchar(20),@shortname varchar(50),@fullname varchar(50),
@tbname varchar(20),@keyfldvarchar(20),@pretbname varchar(20),@dschain varchar(100),
@predsname varchar(20),@prelnkfld varchar(20),@bizType varchar(10),@bizid int,@tagid int,
@tbdatabase varchar(30)
--前数据源信息变量
declare @pdsid int,@pdsname varchar(20),@pshortname varchar(50),@pfullname varchar(50),
@ptbname varchar(20),@pkeyfldvarchar(20),@isDetailTable int,@row int ,@col int,
@ppredsname varchar(20),@pprelnkfld varchar(20),@pbizType varchar(10),@pbizid int,@ptagid int,
@isupper int,@isroot int,@forupdate int,@fordelete int,@forinsert int,@sqlCond varchar(1000),@sqlGrp varchar(1000),
@idParamVar varchar(50),@getOrder int


 --dsID,preDSName dsNameshortname fullName keyval biztype bizid preLnkFld tbNamekeyfld 
--定义主循环游标

set @dealCnt = 1
WHILE (@dealCnt>0)  --第一重循环，只要第二重循环有记录处理，就继续循环
BEGIN

declare mycursor Cursor Static for 
select dsid,predsname,dsname,shortname,fullname,tbname,prelnkfld,biztype,bizid,pretbname,dschain,tagid,row,col,
isupper,isroot,forupdate,fordelete,forinsert,sqlCond,sqlGrp,idParamVar,getOrder
from flatDSS
where parseid=@parseid
order by dsid

OPEN mycursor
--打开游标
select @dealCnt = 0
--循环：每次处理一个数据源
FETCH NEXT FROM mycursor INTO 
@dsid,@predsname,@dsname,@shortname,@fullname,@tbname,@prelnkfld,@biztype,@bizid,@pretbname,@dschain,@tagid,@row,@col,
@isupper,@isroot,@forupdate,@fordelete,@forinsert,@sqlCond ,@sqlGrp ,@idParamVar ,@getOrder 
WHILE @@FETCH_STATUS =0
BEGIN
--处理过的记录，不再处理
if (@tbname is not null and @tbname != '')
goto nxt

-- 1 最简单情况： 本身存在 biztype 和 bizid ，
if (@biztype is not null and @bizid is not null)  --主要针对 this
begin
--@cmpid ,@biztype,@bizid,@tagid,@tablename,@pkfld varchar(30) output
exec sys_sql_getTableNamePk @cmpid,@biztype,@bizid,@tagid,@tbname output,@keyfld output,@tbdatabase output
--错误检查
if (@tbname is null or @keyfld is null)
begin
select @errmsg='行:' + convert(varchar(5),@row) + ' 列:' + convert(varchar(8),@col) + ' ' + @shortname + ' 未配置表名或主键字段 '
return
end
if (@tbname is not null)
begin
set @dealCnt =  1

--更改临时表
update flatDSS
set tbname=@tbname,keyfld=@keyfld,tbDataBase=@tbdatabase
where dsid=@dsid
end
goto nxt

end

-- 2 普通数据源，前级表名称
-- 3 特殊数据源，this.上级 ; this.上级.报销人  ； this.上级.上级.报销人 
--游标：可变业务类型数据源
declare varBizCur Cursor Static For
select biztype,bizid,tagid,tbname
from flatDSS
where parseid = @parseid and dsName=@predsname
order by dsid

Open varBizCur
Fetch Next From varBizCur Into @pbiztype,@pbizid,@ptagid,@ptbname

declare @cnt int
set @cnt = 0
-- 3.1 
While @@FETCH_STATUS=0
Begin

if (@shortname = '上级' or @shortname='根')
begin-- 3.1.1
set @dealCnt =  1
 
--前级可能对于多个物理表, 
insert into flatDSS(predsname,dsname,shortname,fullname, biztype,bizid,tagid,tbname,keyfld,prelnkfld,pretbname,prekeyfld,parseid,dschain,row,col,
isupper,isroot,forupdate,fordelete,forinsert,sqlCond,sqlGrp,idParamVar,getOrder)
select @predsname,@dsname,@shortname,@fullname,upbiztype,upbizid,uptagid,uptablename,upkeyfld,@prelnkfld,tablename,keyfld,@parseid,@dschain,@row,@col,
@isupper,@isroot,@forupdate,@fordelete,@forinsert,@sqlCond,@sqlGrp,@idParamVar,@getOrder
from sys_sql_uptables
where cmpid=@cmpid and biztype=@pbiztype and bizid=@pbizid and tagid=@ptagid
if (@@rowcount>0)
--记录重新从 sys_sql_uptables中读入，原来记录删除
delete flatDSS where dsid=@dsid
else
update flatDSS
set biztype='BIZ',bizid=-1,tagid=0,predsname=@predsname
  where dsid=@dsid
Close varBizCur
DEALLOCATE varBizCur --可变数据源

goto nloop
end ---- 3.1.1

if (@shortname != '上级')
begin--3.1.2  不等于上级，那么
--@fbiztype,@fbizid,@ftagid,@sourcename,@rbiztype output,@rbizid output,
--@rtagid int output,@flindfld varchar(30) output,--父亲的连接字段 @isDetailTable int output
exec sys_sql_getDatasource 
@pbiztype ,@pbizid ,@ptagid,@shortname,
@biztype output,@bizid output,@tagid output,@prelnkfld output,@isDetailTable output

select @ptbname = tbname,@pkeyfld=keyfld
from flatDSS
where parseid=@parseid and biztype=@pbiztype and bizid=@pbizid

--获得物理表名和主键名称
exec sys_sql_getTableNamePk @cmpid,@biztype,@bizid, @tagid,@tbname output,@keyfld output,@tbdatabase output
--错误检查
if (@tbname is null or @keyfld is null)
begin
select @errmsg='行:' + convert(varchar(5),@row) + ' 列:' + convert(varchar(8),@col) + ' ' + @shortname + ' 未配置表名或主键字段 '
return
end

if (@tbname is not null)
begin
set @dealCnt =  1
if (@cnt != 0)
begin
insert into flatDSS(parseid,dsname,shortname,fullname,predsname,dschain)
select parseid,dsname,shortname,fullname,predsname,dschain
from flatDSS
where  dsid=@dsid
select @dsid=@@IDENTITY
end
--更改临时表
update flatDSS
set tbname=@tbname,
biztype=@biztype,
bizid=@bizid,
keyfld=@keyfld,
prelnkfld=@prelnkfld,
pretbname= @ptbname,
prekeyfld=@pkeyfld,
tagid=@tagid,
isDetailTable=@isDetailTable
where dsid=@dsid
end
end  --3.1.2

select @cnt=@cnt + 1

Fetch Next From varBizCur Into @pbiztype,@pbizid,@ptagid,@ptbname
End   -- 3.1 while 可变数据源cursor

Close varBizCur
DEALLOCATE varBizCur --可变数据源


--下一数据源
nxt:
FETCH NEXT FROM mycursor INTO 
@dsid,@predsname,@dsname,@shortname,@fullname,@tbname,@prelnkfld,@biztype,@bizid,@pretbname,@dschain,@tagid,@row,@col,
@isupper,@isroot,@forupdate,@fordelete,@forinsert,@sqlCond ,@sqlGrp ,@idParamVar ,@getOrder 
END  --End 游标循环

nloop:
CLOSE mycursor--关闭游标
DEALLOCATE mycursor --释放游标

END   --End While DealCnt>0



update flatDSS
set parseid=@parseid
where parseid is null

-- 日志表
declare logcursor Cursor Static for 
select distinct tbname
from flatDSS
where parseid=@parseid and bizid>=0
Open logcursor
Fetch Next From logcursor into @tbname
While (@@Fetch_Status=0)
Begin
if (@tbname is not null)
begin
select @tbname = 'zog_'+@tbname 
exec sys_sql_genlogtable @tbname 
end
Fetch Next From logcursor into @tbname
end
CLOSE logcursor
DEALLOCATE logcursor

update flatDSS
set orderNum=20
update flatDSS
set orderNum=1
where shortname='this'

update flatDSS
set orderNum=2
where shortname='user'

update flatDSS
set orderNum=3
where shortname='depart'

update flatDSS
set orderNum=4
where shortname='branch'

update flatDSS
set orderNum=5
where shortname='company'

--标记明细表后继数据源
update flatDSS
set isDTPost=0
update flatDSS
set isDTPost=1
from (select dsname from flatDSS where isDetailTable=1) b
where charindex(b.dsname,dschain)>=1

END