清除核算维度无效引用后台逻辑原创
金蝶云社区-战斗的凯文
战斗的凯文
22人赞赏了该文章 183次浏览 未经作者许可,禁止转载编辑于2024年03月08日 16:34:44

    核算维度经长期使用后,由于原引用它的业务对象被删除或修改,原有引用关系已不存在,有可能数据库中存在一些无效引用,即有些核算维度组合ID已不被任何业务对象引用,这样的ID,理论上是可以删除的,以节省空间和提高查询效率。

    星空提供了清理此类无效引用的功能,位于【科目】的【选项】菜单下,如下图所示:

image.png

    本文将讲述该功能背后的实现逻辑,详细实现过程如下:

1,获取所有引用了核算维度的业务对象:

SELECT DISTINCT V.FOBJECTTYPENAME,V.FTABLENAME ,V.FFIELDNAME
FROM(
    SELECT SYSOBJECTS.NAME AS TABLE_NAME, SYSCOLUMNS.NAME AS COLUMN_NAME, SYSCOLUMNS.COLID AS COLUMN_ID,
         SYSTYPES.NAME AS DATA_TYPE, SYSCOLUMNS.LENGTH AS DATA_LENGTH, SYSCOLUMNS.PREC AS DATA_PRECISION,
         SYSCOLUMNS.SCALE AS DATA_SCALE, SYSCOLUMNS.ISNULLABLE AS NULLABLE, SYSCOMMENTS.TEXT AS DATA_DEFAULT
    FROM SYSCOLUMNS
         INNER JOIN SYSOBJECTS ON SYSCOLUMNS.ID=SYSOBJECTS.ID AND SYSOBJECTS.XTYPE='U'
         INNER JOIN SYSTYPES ON SYSCOLUMNS.XUSERTYPE=SYSTYPES.XUSERTYPE
         LEFT JOIN SYSCOMMENTS ON SYSCOLUMNS.CDEFAULT=SYSCOMMENTS.ID
)U
INNER JOIN(
    SELECT FOBJECTTYPEID, FDEVTYPE, FINHERITPATH, UPPER(FTABLENAME) FTABLENAME,
         UPPER(FFIELDNAME) FFIELDNAME, FBASEOBJECTID FBASEOBJECTID,
         T_META_OBJECTTYPE_L.FNAME FOBJECTTYPENAME
    FROM T_META_OBJECTTYPEREF
                   INNER JOIN T_META_OBJECTTYPE M ON(
                   T_META_OBJECTTYPEREF.FOBJECTTYPEID=M.FID AND(M.FMODELTYPEID !=1400)
                   )
                   LEFT OUTER JOIN T_META_OBJECTTYPE_L ON(
                   T_META_OBJECTTYPEREF.FOBJECTTYPEID=T_META_OBJECTTYPE_L.FID AND FLOCALEID=2052
                   )
    WHERE FREFOBJECTTYPEID='BD_FLEXITEMDETAILV'
)V ON( U.TABLE_NAME=V.FTABLENAME AND U.COLUMN_NAME=V.FFIELDNAME)
UNION  ALL
SELECT '科目余额表','T_GL_BALANCE','FDETAILID'
UNION  ALL
SELECT '调整期科目余额表','T_GL_BALANCEADJUST','FDETAILID'
UNION  ALL
SELECT '损益余额表','T_GL_BALANCEPROFIT','FDETAILID'
UNION  ALL
SELECT '数量余额表','T_GL_BALANCEQTY','FDETAILID'
UNION  ALL
SELECT '调整期数量余额表','T_GL_BALANCEQTYADJUST','FDETAILID'
UNION  ALL
SELECT 'AM科目余额表','T_AM_BALANCE','FDETAILID'
UNION  ALL
SELECT '业务凭证分录表','T_BAS_VOUCHERENTRY','FDETAILID'
UNION  ALL
SELECT '总账凭证分录表','T_GL_VOUCHERENTRY','FDETAILID'

image.png

2,创建临时表TMP,用于存放所有已使用过的核算维度组合ID:

CREATE TABLE TMP (FDETAILID INT PRIMARY KEY)
--插件两个特殊值
INSERT INTO TMP(FDETAILID) VALUES(0)
INSERT INTO TMP(FDETAILID) VALUES(1)

3,分别查询出上述表已使用过的核算维度组合ID并存到临时表中,以T_GL_VOUCHERENTRY表示例如下: 

注,所有上述引用表都要执行一次

INSERT INTO TMP (FDETAILID)
SELECT DISTINCT T0.FDETAILID AS FDETAILID FROM T_GL_VOUCHERENTRY T0
LEFT JOIN TMP T1 ON T1.FDETAILID=T0.FDETAILID
WHERE T0.FDETAILID>1 AND T1.FDETAILID IS NULL

4,以下是需要删除数据的表及核算维度组合ID字段名:

         T_BD_FLEXITEMDETAILV  FID
         T_GL_BALANCE  FDETAILID
         T_GL_BALANCEQTY FDETAILID
         T_GL_BALANCEPROFIT    FDETAILID
         T_GL_BALANCEADJUST   FDETAILID
         T_GL_BALANCEQTYADJUST     FDETAILID

5,对上面的几个表,分别执行删除脚本,删除无效的核算维度记录,执行前一定要备份好数据,以T_BD_FLEXITEMDETAILV表示例:

--备份数据表
SELECT * INTO T_BD_FLEXITEMDETAILV_0308 FROM T_BD_FLEXITEMDETAILV
--删除A表中在B表中不存在的数据
DELETE A FROM T_BD_FLEXITEMDETAILV A
LEFT JOIN TMP B ON A.FID=B.FDETAILID
WHERE B.FDETAILID IS NULL

 

注,上述步骤3到5,可改写为放在游标中循环调用,此处略。


赞 22