Macro DA#(5): Notas/notas de uso, descargas, funciones que se agregarán en el futuro, notas

En este artículo, analizamos las precauciones/referencias para usar la macro DA#, las descargas, las funciones que se agregarán en el futuro y las notas.

Esta es una continuación del artículo anterior.

Macro DA# (4): Función macro DA# (3) -Reversa

3. Precauciones/notas para usar la macro DA#

3.1. Precauciones para el uso de la macro DA#

  • Se recomienda hacer una copia de seguridad del archivo de modelo DA# v5 de destino antes de ejecutar Establecer macro para entidad/atributo.
  • Esto se debe a que Deshacer está deshabilitado en Macros para evitar errores de falta de memoria y mejorar el rendimiento.
  • Los elementos UDP deben crearse previamente en el modelo. La versión macro DA# distribuida actualmente (v2.12) no crea elementos UDP. Esto es para evitar el problema de que se cree un UDP incorrecto al ingresar el nombre de UDP incorrecto y ejecutar la macro. (Se implementará en una versión futura)
  • Los elementos UDP se pueden agregar/eliminar/secuenciar agregar/eliminar/secuenciar se pueden cambiar, pero los elementos predeterminados no se agregan/eliminan/secuencian.

3.2. Notas de la macro DA#

3.2.1. Método de ejecución simultánea inversa

La función inversa puede procesar secuencialmente varios modelos especificados en el archivo de entrada. Si tarda demasiado, los archivos se pueden dividir por modelo y procesar simultáneamente.

Al dividir un archivo, solo necesita dejar el modelo de destino en la hoja "Modelo". Incluso si hay información sobre todo el modelo en las hojas "Tabla", "Columna" y "FK", Invertir se ejecuta en función de la hoja "Modelo".

Para procesar al mismo tiempo en una PC, ejecute varias instancias de Excel y designe y ejecute el archivo modelo que se procesará en cada instancia.

(Referencia: Descripción general de la herramienta de búsqueda del diccionario coreano/inglés de Naver – 3.2. Cómo ejecutar múltiples procesos de Excel)

Sin embargo, el procesamiento simultáneo en una PC no se procesa más rápido de lo esperado debido a la contención de recursos de la CPU. Si lo divide y lo ejecuta en varias PC, puede procesarlo rápidamente al mismo tiempo.

3.2.2. Acciones cuando la macro DA# no funciona normalmente

Medidas a tomar cuando ocurran los siguientes fenómenos.

  • fenómeno
    • Cuando revisé el administrador de tareas, DA# v5 (Modeler5.exe) se está ejecutando (Instancia #1) y con un modelo abierto,
    • Cuando hace clic en el botón "Agregar modelo abierto" en la macro DA#, se crea un nuevo proceso Modeler5.exe (Instancia #2) y se muestra el mensaje "No hay modelo abierto".
    • Un fenómeno en el que la información del modelo abierta en la instancia existente #1 no se puede importar
  • causa
    • Ocurre cuando la información no se refleja correctamente en el Registro cuando se instala DA#.
    • Si ocurre este fenómeno, no hay problema en usar DA#, pero no se ejecuta normalmente cuando se ejecuta DA# con API.
  • Qué hacer
    • Ejecute el símbolo del sistema en modo administrador (¡importante!)y vuelva a registrar el objeto DA# v5 ingresando el siguiente comando.
    • Si DA# está instalado en una ruta diferente a la predeterminada, muévase a esa ruta y ejecute el comando "RegisterServer.bat".
cd "C:\Program Files (x86)\ENCORE\DATAWARE_DA5\DA Modeler"
RegisterServer.bat

Después de ejecutar el comando anterior, vuelva a ejecutar la macro DA# para comprobar si se ha resuelto la anomalía.

3.2.3. SQL de recopilación de información inversa (para Oracle)

Este es un ejemplo de SQL que recopila la lista de tablas, columnas y FK necesarios para invertir en Oracle Database.

Se requiere el permiso "SELECCIONAR CUALQUIER DICCIONARIO" para ejecutar este SQL.

-- TABLE 목록
SELECT ROW_NUMBER() OVER(ORDER BY A.OWNER, A.TABLE_NAME) AS RNO
      ,'모델1' AS 모델명, '주제영역1' AS 주제영역명, '그룹1' AS 엔터티그룹명
      ,CASE
         WHEN INSTR(T.COMMENTS, CHR(10)) > 0 THEN A.TABLE_NAME -- COMMENT에 행분리 문자가 있는 경우 엔터티명 부적합하여 테이블명으로 사용
         WHEN T.COMMENTS IS NOT NULL THEN T.COMMENTS
         ELSE A.TABLE_NAME
       END AS 엔터티명
      ,A.TABLE_NAME AS 테이블명
      ,TRIM(TO_CHAR(A.NUM_ROWS, '9,999,999,999,999')) AS 동의어 -- 동의어에 총건수를 문자형으로 추출(comma 포함)
      ,A.TABLE_NAME AS 보조명
      ,A.OWNER AS DBOWNER
      ,NULL AS 분류, NULL AS "LEVEL", NULL AS 단계, NULL AS 유형, NULL AS 표준화, NULL AS 상태, NULL AS 발생주기, NULL AS 월간발생량, NULL AS "보존기한(월)"
      ,A.NUM_ROWS 총건수
      ,T.COMMENTS AS 정의
      ,NULL AS 데이터처리형태, NULL AS 특이사항, NULL AS Note, NULL AS TAG
      ,O.CREATED, O.LAST_DDL_TIME, A.LAST_ANALYZED, A.TEMPORARY
      ,'[COMMENT]: ' || T.COMMENTS || CHR(13) || CHR(10) ||
       '[NUM_ROWS]: ' || TRIM(TO_CHAR(A.NUM_ROWS, '9,999,999,999,999')) || CHR(13) || CHR(10) ||
       '[CREATED]: ' || TO_CHAR(O.CREATED, 'YYYY-MM-DD HH24:MI:SS') || CHR(13) || CHR(10) ||
       '[LAST_DDL_TIME]: ' || TO_CHAR(O.LAST_DDL_TIME, 'YYYY-MM-DD HH24:MI:SS') || CHR(13) || CHR(10) ||
       '[LAST_ANALYZED]: ' || TO_CHAR(A.LAST_ANALYZED, 'YYYY-MM-DD HH24:MI:SS') AS 정의2
  FROM DBA_TABLES A INNER JOIN DBA_OBJECTS O
         ON   ( A.OWNER = O.OWNER
            AND A.TABLE_NAME = O.OBJECT_NAME
            AND O.OBJECT_TYPE = 'TABLE')
       LEFT OUTER JOIN DBA_TAB_COMMENTS T
         ON   ( A.OWNER = T.OWNER
            AND A.TABLE_NAME = T.TABLE_NAME )
 WHERE 1=1
   AND A.TABLE_NAME NOT LIKE 'BIN$%'
   AND A.OWNER IN ('OWNER1', 'OWNER2')  -- 해당 OWNER 지정
--   AND A.TABLE_NAME = 'TABLE_NAME' -- 특정 TABLE만 포함 또는 제외
 ORDER  BY A.OWNER, A.TABLE_NAME
;

-- COLUMN 목록
WITH WC AS (
SELECT A.OWNER, A.TABLE_NAME, A.COLUMN_NAME, A.COLUMN_ID, A.DATA_TYPE
      ,CASE WHEN A.DATA_TYPE= 'NUMBER' AND A.DATA_SCALE > 0 THEN A.DATA_PRECISION||','||A.DATA_SCALE
            WHEN A.DATA_TYPE= 'NUMBER' AND A.DATA_SCALE = 0 THEN TO_CHAR(A.DATA_PRECISION)
            WHEN A.DATA_TYPE= 'NUMBER' AND A.DATA_SCALE IS NULL THEN ''
            WHEN A.DATA_TYPE IN ('DATE','TIMESTAMP','BLOB', 'CLOB')  THEN NULL
            WHEN A.DATA_TYPE LIKE 'TIMESTAMP%' THEN NULL
            ELSE TO_CHAR(A.DATA_LENGTH)
       END AS DATA_LENGTH
      ,A.DATA_PRECISION, A.DATA_SCALE
      ,DECODE(A.NULLABLE, 'Y','N','Y') AS NOT_NULL
      ,DECODE(B.COLUMN_NAME, NULL, 'N', 'Y') PRI_KEY
      ,B.POSITION PK_POSITION
      ,T.COMMENTS
      ,A.DEFAULT_LENGTH
--      ,A.DATA_DEFAULT
      ,CASE
         WHEN A.DEFAULT_LENGTH IS NULL THEN NULL
         ELSE EXTRACTVALUE
           ( DBMS_XMLGEN.GETXMLTYPE
             ( 'SELECT DATA_DEFAULT FROM DBA_TAB_COLUMNS WHERE OWNER = ''' || A.OWNER || ''' AND TABLE_NAME = ''' || A.TABLE_NAME || ''' AND COLUMN_NAME = ''' || A.COLUMN_NAME || '''' )
           , '//text()' )
       END AS DATA_DEFAULT
      ,A.LAST_ANALYZED, A.NUM_DISTINCT
--      ,A.LOW_VALUE
      ,DECODE(DATA_TYPE
              ,'NUMBER'       ,TO_CHAR(UTL_RAW.CAST_TO_NUMBER(LOW_VALUE))
              ,'VARCHAR2'     ,TO_SINGLE_BYTE(UTL_RAW.CAST_TO_VARCHAR2(LOW_VALUE))
              ,'CHAR'         ,TO_SINGLE_BYTE(UTL_RAW.CAST_TO_VARCHAR2(LOW_VALUE))
              ,'NVARCHAR2'    ,TO_CHAR(UTL_RAW.CAST_TO_NVARCHAR2(LOW_VALUE))
              ,'BINARY_DOUBLE',TO_CHAR(UTL_RAW.CAST_TO_BINARY_DOUBLE(LOW_VALUE))
              ,'BINARY_FLOAT' ,TO_CHAR(UTL_RAW.CAST_TO_BINARY_FLOAT(LOW_VALUE))
              ,'DATE',DECODE(LOW_VALUE, NULL, NULL, TO_CHAR(1780+TO_NUMBER(SUBSTR(LOW_VALUE,1,2),'XX')
                     +TO_NUMBER(SUBSTR(LOW_VALUE,3,2),'XX'))||'-'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(LOW_VALUE,5,2), 'XX'), '00'))||'-'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(LOW_VALUE,7,2), 'XX'), '00'))||' '
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(LOW_VALUE,9,2),'XX')-1, '00'))||':'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(LOW_VALUE,11,2),'XX')-1, '00'))||':'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(LOW_VALUE,13,2),'XX')-1, '00')))
              ,LOW_VALUE
              ) LOW_VALUE
--      ,A.HIGH_VALUE
      ,DECODE(DATA_TYPE
              ,'NUMBER'       ,TO_CHAR(UTL_RAW.CAST_TO_NUMBER(HIGH_VALUE))
              ,'VARCHAR2'     ,TO_SINGLE_BYTE(UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE))
              ,'CHAR'         ,TO_SINGLE_BYTE(UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE))
              ,'NVARCHAR2'    ,TO_CHAR(UTL_RAW.CAST_TO_NVARCHAR2(HIGH_VALUE))
              ,'BINARY_DOUBLE',TO_CHAR(UTL_RAW.CAST_TO_BINARY_DOUBLE(HIGH_VALUE))
              ,'BINARY_FLOAT' ,TO_CHAR(UTL_RAW.CAST_TO_BINARY_FLOAT(HIGH_VALUE))
              ,'DATE',DECODE(HIGH_VALUE, NULL, NULL, TO_CHAR(1780+TO_NUMBER(SUBSTR(HIGH_VALUE,1,2),'XX')
                     +TO_NUMBER(SUBSTR(HIGH_VALUE,3,2),'XX'))||'-'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(HIGH_VALUE,5,2), 'XX'), '00'))||'-'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(HIGH_VALUE,7,2), 'XX'), '00'))||' '
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(HIGH_VALUE,9,2),'XX')-1, '00'))||':'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(HIGH_VALUE,11,2),'XX')-1, '00'))||':'
                   ||TRIM(TO_CHAR(TO_NUMBER(SUBSTR(HIGH_VALUE,13,2),'XX')-1, '00')))
              ,HIGH_VALUE
               ) HIGH_VALUE
      ,TB.NUM_ROWS, A.NUM_NULLS, A.CHAR_USED, A.AVG_COL_LEN
  FROM DBA_TABLES TB LEFT OUTER JOIN DBA_TAB_COLUMNS A
         ON (TB.OWNER = A.OWNER
         AND TB.TABLE_NAME = A.TABLE_NAME)
       LEFT OUTER JOIN
       (SELECT C.OWNER, C.TABLE_NAME, C.COLUMN_NAME, C.POSITION
          FROM DBA_CONS_COLUMNS C INNER JOIN DBA_CONSTRAINTS S
                 ON  ( C.OWNER = S.OWNER
                   AND C.TABLE_NAME = S.TABLE_NAME
                   AND C.CONSTRAINT_NAME = S.CONSTRAINT_NAME )
         WHERE S.CONSTRAINT_TYPE = 'P'
       ) B
         ON  ( A.OWNER = B.OWNER
           AND A.TABLE_NAME = B.TABLE_NAME
           AND A.COLUMN_NAME = B.COLUMN_NAME )
       LEFT OUTER JOIN ALL_COL_COMMENTS T
         ON  ( T.OWNER = A.OWNER
           AND T.TABLE_NAME = A.TABLE_NAME
           AND T.COLUMN_NAME = A.COLUMN_NAME )
 WHERE 1=1
   AND A.OWNER IN ('OWNER1', 'OWNER2')  -- 해당 OWNER 지정
   AND A.TABLE_NAME NOT LIKE 'BIN$%'
   AND NOT EXISTS ( SELECT 'X'  -- View column 제외 조건
                      FROM DBA_VIEWS V
                     WHERE V.OWNER = A.OWNER
                       AND V.VIEW_NAME = A.TABLE_NAME )
   --AND A.TABLE_NAME = 'TABLE_NAME'
-- ORDER BY OWNER, TABLE_NAME, COLUMN_ID
)
SELECT ROW_NUMBER() OVER(ORDER BY OWNER, TABLE_NAME, COLUMN_ID) AS RNO
--      ,ROW_NUMBER() OVER(PARTITION BY OWNER, TABLE_NAME ORDER BY COLUMN_ID) AS COLNO
      ,'모델1' AS 모델명
      ,'' AS 엔터티명
      ,CASE
         WHEN INSTR(COMMENTS, CHR(10)) > 0 THEN COLUMN_NAME -- COMMENT에 행분리 문자가 있는 경우 속성명 부적합하여 컬럼명으로 사용
         WHEN COMMENTS IS NOT NULL THEN COMMENTS
         ELSE COLUMN_NAME
       END AS 속성명
      ,TABLE_NAME AS 테이블명
      ,COLUMN_NAME AS 컬럼명
      ,COMMENTS AS 정의
      ,COLUMN_NAME AS 보조명
      ,COLUMN_NAME AS 동의어
      ,TABLE_NAME AS Reverse테이블명
      ,COLUMN_NAME AS Reverse컬럼명
      ,DATA_TYPE AS ReverseType
      ,DATA_LENGTH AS ReverseLENGTH
      ,PRI_KEY AS PK
      ,NOT_NULL AS NOTNULL
      ,NULL AS 유형
      ,DATA_TYPE AS 데이터타입
      ,DATA_PRECISION AS 길이
      ,DATA_SCALE AS 소수점
      ,DATA_DEFAULT AS 기본값
      ,NULL AS 기본값, NULL AS 도메인, NULL AS "FK", NULL AS 핵심속성여부, NULL AS 본질식별자여부
      ,NULL AS 보조식별자여부, NULL AS 표준동기화여부, NULL AS 비상속여부, NULL AS 표준화
      ,NULL AS 정보보호여부, NULL AS 정보보호등급, NULL AS 암호화여부, NULL AS 스크램블
      ,'[COMMENT]: ' || COMMENTS || CHR(13) || CHR(10) ||
       '[NUM_ROWS]: ' || TRIM(TO_CHAR(NUM_ROWS, '9,999,999,999,999')) || CHR(13) || CHR(10) ||
       '[NUM_DISTINCT]: ' || TRIM(TO_CHAR(NUM_DISTINCT, '9,999,999,999,999')) || CHR(13) || CHR(10) ||
       '[NUM_NULLS]: ' || TRIM(TO_CHAR(NUM_NULLS, '9,999,999,999,999')) || CHR(13) || CHR(10) ||
       '[NULL%] : ' || DECODE(NVL(NUM_ROWS, 0), 0, 0, ROUND(NUM_NULLS / NUM_ROWS, 5) * 100) || '%' || CHR(13) || CHR(10) ||
       '[MIN_VALUE]: ' || LOW_VALUE || CHR(13) || CHR(10) ||
       '[MAX_VALUE]: ' || HIGH_VALUE  AS 정의2
--      ,WC.*
  FROM WC
 WHERE NUM_NULLS > 0
 ORDER BY OWNER, TABLE_NAME, COLUMN_ID
;

-- FK 목록
WITH WFK AS (
SELECT DISTINCT
       C2.OWNER AS P_OWNER
      ,C2.TABLE_NAME P_TABLE_NAME
      ,LISTAGG (C2.COLUMN_NAME, ',') WITHIN GROUP (ORDER BY C2.POSITION)
         OVER ( PARTITION BY C1.OWNER, C1.TABLE_NAME, C1.CONSTRAINT_NAME, C2.OWNER, C2.TABLE_NAME) AS P_COLUMN_LIST
      ,C1.OWNER AS C_OWNER
      ,C1.TABLE_NAME AS C_TABLE_NAME
      ,C1.CONSTRAINT_NAME AS C_CONSTRAINT_NAME
  FROM DBA_CONSTRAINTS C1 INNER JOIN DBA_CONS_COLUMNS C2
         ON (C1.R_CONSTRAINT_NAME = C2.CONSTRAINT_NAME
         AND C1.R_OWNER = C2.OWNER)
 WHERE C1.OWNER IN ('OWNER1', 'OWNER2')  -- 해당 DB의 테이블 OWNER 지정
   AND C1.CONSTRAINT_TYPE = 'R'
 ORDER BY C2.OWNER, C2.TABLE_NAME
)
SELECT '모델1' AS 모델명
      ,P_TABLE_NAME AS 부모엔터티명
      ,P_TABLE_NAME AS 부모테이블명
      ,C_TABLE_NAME AS 자식엔터티명
      ,C_TABLE_NAME AS 자식테이블명
      ,P_TABLE_NAME || '->' || C_TABLE_NAME AS 관계명
      ,NULL AS 정의, NULL AS 관계유형, NULL AS 기수성, NULL AS 선택성, NULL AS 식별성
      ,NULL AS 부모엔터티관계동사, NULL AS 자식엔터티관계동사
  FROM WFK
;

Cuando utilice el SQL anterior, consulte lo siguiente.

  • Compruebe el propietario de destino (esquema) y modifíquelo. (líneas 32, 116, 179)
  • Seleccione si desea designar la definición de la tabla como un comentario (línea 15) o como un valor que combina varias columnas (líneas 18-22).
  • La definición de columna utiliza la información estadística de Oracle para extraer la siguiente información.
    • COMENTARIO: comentario de columna
    • NUM_ROWS: Número de filas de la tabla
    • NUM_DISTINCT: número de valores con duplicados eliminados
    • NUM_NULLS: Recuento de filas donde el valor de la columna correspondiente es NULL
    • NULL%: (NUM_NULLS / NUM_ROWS) * Proporción de filas nulas de todas las filas calculadas como 100
    • MIN_VALUE: El valor mínimo de la columna correspondiente (extraído de DBA_TAB_COLUMNS.LOW_VALUE según DATA_TYPE)
    • MAX_VALUE: El valor máximo de la columna (extraído de DBA_TAB_COLUMNS.HIGH_VALUE según DATA_TYPE)
  • Para MIN_VALUE y MAX_VALUE de la columna, consulte lo siguiente. (Líneas 63-78, 80-95)
    • ORA-29275: Si se produce un error de carácter multibyte parcial, aplique la función to_single_byte y, si el error persiste, excluya los valores máximo y mínimo y extráigalos.
    • Al extraer, excepto los valores máximo y mínimo, modifique la definición de la columna (líneas 158 y 159) juntas.
  • Si lleva mucho tiempo o es imposible obtener la cuenta, la información de acceso y los privilegios para ejecutar SQL, entregue el SQL al DBA o al administrador de TI, guarde el resultado de la ejecución como un archivo de Excel y solicite una respuesta.
  • El resultado de ejecutar los tres SQL se puede recibir como tres archivos (una hoja para cada archivo) o como un archivo (tres hojas).

4. Descarga de macro DA#, funciones que se agregarán en el futuro, nota

4.1. Descargar macro DA#

Puede consultarlo en el repositorio de github a continuación.

https://github.com/DAToolset/DA-Macro

DA# Macro GitHub Repository
Repositorio GitHub de la macro DA#

Alternativamente, puede descargar directamente desde esta URL.

https://github.com/DAToolset/DA-Macro/raw/main/DA%23%20Macro_v2.12_20210814.xlsm

4.2. Función de macro DA# que se agregará en el futuro

DA# Macro planea agregar las siguientes funciones además de las funciones implementadas actualmente.

  • Obtener/establecer propiedades de subtipo: Obtener/establecer propiedades administradas dentro de un subtipo (incluidas las propiedades jerárquicas)
  • AR Model Get/Set: obtenga/establezca modelos AR al consultarlos en Treeview y seleccionar varios modelos
  • Relación Obtener/Establecer: Relación Obtener/Establecer entre Entidades
  • Ampliar los métodos de colocación de entidades

4.3. Nota para los usuarios

Solicitudes de errores, mejoras de funciones, funciones adicionales, etc., envíenos comentarios de blog o correos electrónicos. Sin embargo, dado que esta herramienta se está desarrollando como un pasatiempo, no es posible responder rápidamente a los requisitos. Cuando tenga tiempo libre, reflexionaré y distribuiré la función cuando sea necesario. El ciclo de distribución tampoco es regular.

El código fuente se proporciona junto, por lo que si tiene alguna función necesaria, le agradeceríamos mucho que la reflejara y la compartiera conmigo nuevamente.


Hasta ahora, hemos aprendido todo sobre cómo usar la Macro DA#. A continuación, echaremos un vistazo al código fuente de DA# Macro.


<< Lista de artículos relacionados >>

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

es_ESEspañol