【问题标题】:Finding matching string among two columns from two different tables在两个不同表的两列中查找匹配字符串
【发布时间】:2017-03-17 13:57:28
【问题描述】:

select * from all_tables 获取数据库中的所有表

   Table A
    Name     Shortform
    Generate GNRT
    Support  SPRT  
    and so onn..

大约有 100 个表名和 50 个英文名以及缩写形式 每个表名都是使用缩写形式创建的,例如 SELECT * FROM GNRT_SPRT
如果一个新人尝试创建表并且不遵循简写形式,那么应该在名为 results 的新表中获取这些表名。

FOR example:      
select * from gnrte_sche

上面的示例与短格式不匹配,因此应该将表名插入到名为 results 的新表中。我需要使用 select * from all_tables 检查所有表

-output-
Table Results
Diff_tables--column name
gnrte_sche

【问题讨论】:

  • 我是否正确理解您有一个名为“A”的表格,它定义了所有正在考虑的英文单词以及每个单词的简短形式?谢谢
  • @alexgibbs 绝对是的
  • 好的,谢谢。只是为了确认一下,您想在 ALL_TABLES 中查找所有不由 SHORTFORM 组成的 TABLE_NAME?
  • @alexgibbs 是的 .. 我的意思是所有那些不是由短格式组成或与表 A 中的短格式列不匹配的那些应该在不同的表中获取
  • 感谢技术人员。我不太确定“在不同的表中获取”是什么意思,但我会发布一些内容,让您找到 ALL_TABLES 中不由 SHORTFORM 组成的所有 TABLE。您能否同时告诉我您所说的“在不同的表中提取”是什么意思?

标签: string oracle plsql plsqldeveloper


【解决方案1】:

已编辑以包括保存不匹配的内容。
这没有经过调整,可能还有其他更简单的解决方案,但下面可能会满足您的需求。

此块将打印出任何不是仅由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_SPRTWOKI_SPRT 等,因为它们有 SHORTFORMs,但要列出 ROBOTSGNRTE_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

【讨论】:

  • 第一个循环拆分表名,第二个循环将其与简写形式进行比较??
  • 你创建的所有表!!内置的元数据 select * from all_tables 应该给我所有的表,你为什么要再次创建?
  • 感谢@Techie 第一个循环遍历每个表名。第二个循环检查它是否仅由缩写和下划线组成。我创建了额外的表格来测试代码并显示操作过程——以确保跳过由简写形式组成的表格,但标记那些不是由简写形式组成的表格。
  • dbms_output.put_line 中的输出能否保存在一个有两列的表中?
  • @Techie 当然可以。我会更新一个例子。
猜你喜欢
  • 1970-01-01
  • 2018-12-07
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多