Oracle
遍歷欄位列表,檢查查找表
我有一個欄位列表:
FIELD_DOMAIN_ENG_VW
+-------------+------------+-------------+ | TABLE_NAME | FIELD_NAME | DOMAIN_NAME | +-------------+------------+-------------+ | ENG.TABLE_1 | FIELD_1 | DOMAIN_ABC | | ENG.TABLE_1 | FIELD_2 | DOMAIN_XYZ | | ENG.TABLE_2 | FIELD_1 | DOMAIN_XYZ | +-------------+------------+-------------+
該視圖查看地理數據庫中的所有表,並列出具有與其關聯的域的所有欄位(域是 GIS 的查找表/驗證表等價物)。
基礎表如下所示:
表格1
+--------------+--------------+ | FIELD_1 | FIELD_2 | | {DOMAIN_ABC} | {DOMAIN_XYZ} | +--------------+--------------+ | A | X | | B | Y | | C | zzzz | | BLACK SHEEP | | +--------------+--------------+
表_2
+--------------+--------------+ | FIELD_1 | FIELD_2 | | {DOMAIN_XYZ} | | +--------------+--------------+ | Z | ... | | Y | | | X | | | asdf | | +--------------+--------------+
域如下所示:
DOMAIN_VALUES_VW
+------------+------+-------------+ | DOMAIN | CODE | DESCRIPTION | +------------+------+-------------+ | DOMAIN_ABC | A | EH | | DOMAIN_ABC | B | BEE | | DOMAIN_ABC | C | SEE | +------------+------+-------------+ | DOMAIN_XYZ | X | EX | | DOMAIN_XYZ | Y | WHY | | DOMAIN_XYZ | Z | ZEE | +------------+------+-------------+
題
出於驗證目的,我進行了一個查詢,該查詢將檢查欄位中是否存在與相應域不匹配的值:
INSERT INTO ENG.CV_ERRORS (TABLE_NAME, FIELD_NAME, ERROR) SELECT 'TABLE_1' AS TABLE_NAME ,'FIELD_1' AS FIELD_NAME ,FIELD_1 AS ERROR FROM ENG.TABLE_1 LEFT JOIN ( SELECT CODE FROM INFRASTR.D_CV_ENG_VW WHERE DOMAIN = 'DOMAIN_ABC' ) ON FIELD_1 = CODE WHERE FIELD_1 IS NOT NULL AND CODE IS NULL
+------------+------------+-------------+ | TABLE_NAME | FIELD_NAME | ERROR | +------------+------------+-------------+ | TABLE_1 | FIELD_1 | BLACK SHEEP | +------------+------------+-------------+
但是,此查詢被硬編碼為一次在單個表中的單個欄位上執行。我需要以程式方式檢查數據庫中所有表中的所有域欄位。
我怎樣才能做到這一點?我很確定這可以用 PL/SQL 和動態 SQL 來完成,但是我對 PL/SQL 太陌生了,以至於它被證明是相當困難的。
本機動態 SQL(在 PL/SQL 匿名塊中):
01 DECLARE 02 l_table_name VARCHAR2(100); 03 l_field_name VARCHAR2(100); 04 l_domain_name VARCHAR2(100); 05 BEGIN 06 DELETE FROM ENG.CV_ERRORS; 07 FOR list_fields IN ( 08 SELECT 09 TABLE_NAME 10 ,FIELD_NAME 11 ,DOMAIN_NAME 12 FROM 13 ENG.FIELD_DOMAIN_ENG_VW 14 WHERE 15 TABLE_NAME NOT LIKE '%ANNO%' 16 ) 17 LOOP 18 l_table_name := list_fields.TABLE_NAME; 19 l_field_name := list_fields.FIELD_NAME; 20 l_domain_name := list_fields.DOMAIN_NAME; 21 22 EXECUTE IMMEDIATE 23 'INSERT INTO ENG.CV_ERRORS 24 (TABLE_NAME, FIELD_NAME, ERROR) 25 SELECT 26 :bv1 AS TABLE_NAME 27 ,:bv2 AS FIELD_NAME 28 , ' || l_field_name || ' AS ERROR 29 FROM ' || 30 l_table_name || 31 ' LEFT JOIN 32 ( 33 SELECT CODE 34 FROM ENG.D_CV_ENG_VW 35 WHERE DOMAIN = :bv3 36 ) 37 ON ' || l_field_name || ' = CODE 40 WHERE 41 ' || l_field_name || ' IS NOT NULL 42 AND 43 CODE IS NULL' 44 45 USING l_table_name, l_field_name, l_domain_name; 46 47 END LOOP; 48 COMMIT; 49 END;
結果集
+------------+------------+-------------+ | TABLE_NAME | FIELD_NAME | ERROR | +------------+------------+-------------+ | TABLE_1 | FIELD_1 | BLACK SHEEP | | TABLE_1 | FIELD_2 | zzzz | | TABLE_2 | FIELD_1 | asdf | +------------+------------+-------------+
腳步
- 刪除所有現有行
ENG.CV_ERRORS
(奇怪的是,我正在使用的 ODBC 連接沒有截斷表的權限)。- 循環遍歷
FIELD_DOMAIN_ENG_VW
.- 對於每個欄位,生成一個動態查詢以查找與相應域不匹配的值。然後將它們插入
ENG.CV_ERRORS
.現在一切都說了又做了,這並不那麼複雜。最難的部分是圍繞綁定變數與字元串連接變數(正確的術語?)以及何時使用它們(儘管我還不完全理解這一點)。
相關問題
初學者 PL/SQL:從動態 SQL 函式(函式,而不是循環)返回行值