已编辑以包括保存不匹配的内容。
这没有经过调整,可能还有其他更简单的解决方案,但下面可能会满足您的需求。
此块将打印出任何不是仅由SHORTFORM 单词和下划线组成的表名,并找到第一个(唯一的)非缩写形式。它还将所有匹配项保存到名为NON_SHORTFORM 的示例表中。它允许前缀和后缀下划线,并允许“$”字符,只要它是在一个 SHORTFORM 中。
这将从TABLE A 读取SHORTFORMs,并评估ALL_TABLES 中的所有内容以检查每个内容是否由SHORTFORMs 组成。当遇到格式错误的TABLE_NAME 时,它会通过DBMS_OUTPUT 将其连同不匹配的单词一起打印出来,并保存不匹配的记录。
首先,创建一个示例A TABLE:
CREATE TABLE A(
NAME VARCHAR2(200) NOT NULL PRIMARY KEY,
SHORTFORM VARCHAR2(30) UNIQUE NOT NULL
);
INSERT INTO A VALUES('Generate','GNRT');
INSERT INTO A VALUES('Support','SPRT');
INSERT INTO A VALUES('Hobbit','HOBT');
INSERT INTO A VALUES('Wookie','WOKI');
INSERT INTO A VALUES('Adventure','AVNTR');
然后创建一些示例TABLEs 进行检查
CREATE TABLE GNRT_SPRT(X NUMBER);
CREATE TABLE WOKI_SPRT(X NUMBER);
CREATE TABLE HOBT_WOKI_AVNTR(X NUMBER);
CREATE TABLE ROBOTS(X NUMBER);
CREATE TABLE GNRTE_SCHE(X NUMBER);
然后创建一个TABLE 来保存不匹配项(请注意,这仅允许为每个 TABLE 保存一个不匹配项。如果您的用例不同,可以根据需要进行调整):
CREATE TABLE NON_SHORTFORM(
OWNER VARCHAR2(128) NOT NULL,
TABLE_NAME VARCHAR2(128) NOT NULL,
MISMATCHED_WORD VARCHAR2(128) NOT NULL,
CONSTRAINT NON_SHORTFORM_PK PRIMARY KEY (OWNER, TABLE_NAME));
然后创建一个BLOCK 来进行评估(如果愿意,可以是FUNCTION 等)。请注意,这允许“$”和数字。如果您想排除这些,也可以调整以下内容:
DECLARE
TYPE V_STRING_LIST IS TABLE OF VARCHAR2(128);
V_SHORT_FORM_SET V_STRING_LIST;
V_SHORT_FORM_MATCHED NUMBER(1,0) := 0;
V_TABLE_NAME VARCHAR2(128);
V_TABLE_NAME_WORK_SPACE VARCHAR2(128);
V_TABLE_TOKEN VARCHAR2(128);
BEGIN
SELECT SHORTFORM BULK COLLECT INTO V_SHORT_FORM_SET FROM A;
DBMS_OUTPUT.PUT_LINE('MALFORMED TABLE-NAMES:');
<<TABLE_NAME_LOOP>>
FOR TABLE_POINTER IN ( SELECT ALL_TABLES.OWNER, ALL_TABLES.TABLE_NAME FROM ALL_TABLES WHERE ALL_TABLES.TABLE_NAME <> 'A')
LOOP
V_TABLE_NAME_WORK_SPACE := REGEXP_REPLACE(TABLE_POINTER.TABLE_NAME,'((^[_]{1,})|([_]{1,}$))',NULL);
<<SHORT_FORM_LOOP>>
LOOP
V_TABLE_NAME_WORK_SPACE := REGEXP_REPLACE(V_TABLE_NAME_WORK_SPACE,'((^[_]{1,})|([_]{1,}$))',NULL);
EXIT WHEN NOT (REGEXP_LIKE(COALESCE(V_TABLE_NAME_WORK_SPACE,'!'),'^[_A-Z0-9$]{1,}$'));
V_TABLE_TOKEN := REGEXP_SUBSTR(V_TABLE_NAME_WORK_SPACE,'^[A-Z0-9$]{1,}');
V_TABLE_NAME_WORK_SPACE := REGEXP_REPLACE(V_TABLE_NAME_WORK_SPACE,'^[A-Z0-9$]{1,}',NULL);
SELECT COUNT(*) INTO V_SHORT_FORM_MATCHED FROM A
WHERE A.SHORTFORM = V_TABLE_TOKEN;
IF NOT V_SHORT_FORM_MATCHED = 1
THEN DBMS_OUTPUT.PUT_LINE(UTL_LMS.FORMAT_MESSAGE('Table-Name:%s,Mismatched-Shortform:%s',TABLE_POINTER.TABLE_NAME,V_TABLE_TOKEN));
MERGE INTO NON_SHORTFORM USING (
SELECT TABLE_POINTER.OWNER AS OWNER,
TABLE_POINTER.TABLE_NAME AS TABLE_NAME,
V_TABLE_TOKEN AS MISMATCHED_WORD
FROM DUAL) CANDIDATE_MISMATCH
ON (NON_SHORTFORM.OWNER = CANDIDATE_MISMATCH.OWNER
AND NON_SHORTFORM.TABLE_NAME = CANDIDATE_MISMATCH.TABLE_NAME)
WHEN MATCHED THEN UPDATE SET NON_SHORTFORM.MISMATCHED_WORD = CANDIDATE_MISMATCH.MISMATCHED_WORD
WHEN NOT MATCHED THEN INSERT (OWNER, TABLE_NAME, MISMATCHED_WORD)
VALUES (CANDIDATE_MISMATCH.OWNER, CANDIDATE_MISMATCH.TABLE_NAME, CANDIDATE_MISMATCH.MISMATCHED_WORD);
EXIT;
END IF;
END LOOP SHORT_FORM_LOOP;
END LOOP TABLE_NAME_LOOP;
END;
/
然后运行它(我希望它忽略 GNRT_SPRT、WOKI_SPRT 等,因为它们有 SHORTFORMs,但要列出 ROBOTS 和 GNRTE_SCHE:
SET SERVEROUTPUT ON;
-- CODE BLOCK FROM GOES HERE
MALFORMED TABLE-NAMES:
... other TABLEs omitted ...
Table-Name:ROBOTS,Mismatched-Shortform:ROBOTS
Table-Name:GNRTE_SCHE,Mismatched-Shortform:GNRTE
并检查保存的不匹配项(注意在此示例中,仅保存找到的第一个不匹配项。如果要保存每个不匹配项,则需要相应地更新上述块):
SELECT * FROM NON_SHORTFORM;
OWNER TABLE_NAME MISMATCHED_WORD
-- Other records omitted
LIMS ROBOTS ROBOTS
LIMS GNRTE_SCHE GNRTE