[SQL] 의 특정 값에 대한 모든 필드에서 모든 테이블을 검색 (오라클)
SQL의 특정 값에 대한 모든 필드에서 모든 테이블을 검색 (오라클)
그것은 오라클에서 특정 값에 대한 모든 테이블의 모든 필드를 검색 할 수 있습니까?
나는이 쿼리에 매우 오랜 시간이 걸릴 수 있습니다 알 수 있도록 일부 테이블의 행 수천 수백 개의 테이블이 있습니다. 하지만 내가 알고있는 유일한 것은 1 / / 22 2008P09RR8 있습니다에 대 한 필드의 값은 내가 쿼리에하고 싶은 것입니다. <
나는이 이름을 지정해야합니다 생각에 따라 적절한 열을 찾을 수 있지만 어떤 결과를 반환하기 위해 아래 나는이 문을 사용하여 시도했습니다.
SELECT * from dba_objects
WHERE object_name like '%DTN%'
이이 데이터베이스에는 문서는 절대로 없습니다 나는이 필드에서 가져온되고 아무 생각이 없습니다.
이견있는 사람?
해결법
-
==============================
1.인용문:
인용문:
열은 목적이 아니다. 당신은 당신이 기대하는 것을 의미하는 경우 열 이름처럼되고 '% DTN %', 당신이 원하는 쿼리는 다음과 같습니다
SELECT owner, table_name, column_name FROM all_tab_columns WHERE column_name LIKE '%DTN%';
'DTN'문자열이 당신의 부분에 그냥 추측, 그러나 만약 그 아마 도움이되지 않습니다.
그건 그렇고, 당신은 '1 / / 22 2008P09RR8'는 하나의 열에서 직접 선택한 값입니다 어떻게 확신? 당신이 어디에서 오는가 전혀 모르는 경우, 그것은 여러 컬럼의 연결, 또는 함수의 결과, 또는 중첩 된 테이블 개체에 앉아 값이 될 수 있습니다. 그래서 당신은 그 값에 대한 모든 열을 확인하려고 기러기 추적에있을 수 있습니다. 이 값을 표시하고 어떤 클라이언트 응용 프로그램을 시작하고 그것을 얻기 위해 사용하는 어떤 쿼리 파악하려고하지 수 있습니까?
어쨌든, diciu의 대답은 값에 대한 모든 테이블의 모든 열을 확인하는 SQL 쿼리를 생성하는 하나의 방법을 제공합니다. 또한 PL / SQL 블록과 동적 SQL을 사용하여 완전히 하나 개의 SQL 세션에서 유사한 물건을 할 수 있습니다. 여기에 그 일부 급하게 작성된 코드는 다음과 같습니다
SET SERVEROUTPUT ON SIZE 100000 DECLARE match_count INTEGER; BEGIN FOR t IN (SELECT owner, table_name, column_name FROM all_tab_columns WHERE owner <> 'SYS' and data_type LIKE '%CHAR%') LOOP EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || t.owner || '.' || t.table_name || ' WHERE '||t.column_name||' = :1' INTO match_count USING '1/22/2008P09RR8'; IF match_count > 0 THEN dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count ); END IF; END LOOP; END; /
당신이 너무 더 효율적으로 만들 수있는 몇 가지 방법이 있습니다.
이 경우, 당신이 찾고있는 가치 부여, 당신은 명확 쿼리 수를 줄일 번호 또는 DATE 유형의 어떤 열을 제거 할 수 있습니다. 유형 '% CHAR %'같은 곳 어쩌면 열로 제한합니다.
대신 열 당 하나 개의 쿼리, 당신은 같은 테이블 당 하나 개의 쿼리를 만들 수있다 :
SELECT * FROM table1 WHERE column1 = 'value' OR column2 = 'value' OR column3 = 'value' ... ;
-
==============================
2.난 당신이 하나 개의 소유자로 검색 할 경우 더 빨리 작동하도록 위의 코드에 약간의 수정을했다. 당신은 3 변수 v_owner, v_data_type을 변경해야하고 당신이 찾고있는 무슨에 맞게 v_search_string.
난 당신이 하나 개의 소유자로 검색 할 경우 더 빨리 작동하도록 위의 코드에 약간의 수정을했다. 당신은 3 변수 v_owner, v_data_type을 변경해야하고 당신이 찾고있는 무슨에 맞게 v_search_string.
SET SERVEROUTPUT ON SIZE 100000 DECLARE match_count INTEGER; -- Type the owner of the tables you are looking at v_owner VARCHAR2(255) :='ENTER_USERNAME_HERE'; -- Type the data type you are look at (in CAPITAL) -- VARCHAR2, NUMBER, etc. v_data_type VARCHAR2(255) :='VARCHAR2'; -- Type the string you are looking at v_search_string VARCHAR2(4000) :='string to search here...'; BEGIN FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||t.table_name||' WHERE '||t.column_name||' = :1' INTO match_count USING v_search_string; IF match_count > 0 THEN dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count ); END IF; END LOOP; END; /
-
==============================
3.여기에 낮은 문자열 일치를 비교합니다 또 다른 수정 된 버전입니다. 이것은 오라클 11g에서 작동합니다.
여기에 낮은 문자열 일치를 비교합니다 또 다른 수정 된 버전입니다. 이것은 오라클 11g에서 작동합니다.
DECLARE match_count INTEGER; -- Type the owner of the tables you are looking at v_owner VARCHAR2(255) :='OWNER_NAME'; -- Type the data type you are look at (in CAPITAL) -- VARCHAR2, NUMBER, etc. v_data_type VARCHAR2(255) :='VARCHAR2'; -- Type the string you are looking at v_search_string VARCHAR2(4000) :='%lower-search-sub-string%'; BEGIN FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||t.table_name||' WHERE lower('||t.column_name||') like :1' INTO match_count USING v_search_string; IF match_count > 0 THEN dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count ); END IF; END LOOP; END; /
-
==============================
4.예 당신은 할 수와 DBA 당신을 싫어하고 그 I / O의 많은 원인이 정말 아래로 캐시 숙청로 데이터베이스 성능을 가지고 있기 때문에 당신이 바닥에 신발을 못을 찾을 수 있습니다.
예 당신은 할 수와 DBA 당신을 싫어하고 그 I / O의 많은 원인이 정말 아래로 캐시 숙청로 데이터베이스 성능을 가지고 있기 때문에 당신이 바닥에 신발을 못을 찾을 수 있습니다.
select column_name from all_tab_columns c, user_all_tables u where c.table_name = u.table_name;
시작합니다.
나는 브이 $ 세션과 브이 $ SQLAREA를 사용하여 실행 쿼리를 시작합니다. 이 작업은 오라클 버전에 따라 변경됩니다. 이 공간이 아니라 공격 모두를 좁힐 것입니다.
-
==============================
5.나는이 오래된 주제 알고있다. 하지만 그것이 오히려 PL / SQL을 사용하는 것보다 SQL에서 할 수 있다면 질문에 댓글을 묻는 참조하십시오. 그래서 솔루션을 게시 할 생각.
나는이 오래된 주제 알고있다. 하지만 그것이 오히려 PL / SQL을 사용하는 것보다 SQL에서 할 수 있다면 질문에 댓글을 묻는 참조하십시오. 그래서 솔루션을 게시 할 생각.
데모 아래는 전체 스키마의 모든 테이블의 모든 열에서 값을 검색하는 것입니다 :
SCOTT 스키마의 값 왕 살펴 보자.
SQL> variable val varchar2(10) SQL> exec :val := 'KING' PL/SQL procedure successfully completed. SQL> SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword", 2 SUBSTR (table_name, 1, 14) "Table", 3 SUBSTR (column_name, 1, 14) "Column" 4 FROM cols, 5 TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select ' 6 || column_name 7 || ' from ' 8 || table_name 9 || ' where upper(' 10 || column_name 11 || ') like upper(''%' 12 || :val 13 || '%'')' ).extract ('ROWSET/ROW/*') ) ) t 14 ORDER BY "Table" 15 / Searchword Table Column ----------- -------------- -------------- KING EMP ENAME SQL>
SCOTT 스키마의 값 (20)에 대한 살펴 보자.
SQL> variable val NUMBER SQL> exec :val := 20 PL/SQL procedure successfully completed. SQL> SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword", 2 SUBSTR (table_name, 1, 14) "Table", 3 SUBSTR (column_name, 1, 14) "Column" 4 FROM cols, 5 TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select ' 6 || column_name 7 || ' from ' 8 || table_name 9 || ' where upper(' 10 || column_name 11 || ') like upper(''%' 12 || :val 13 || '%'')' ).extract ('ROWSET/ROW/*') ) ) t 14 ORDER BY "Table" 15 / Searchword Table Column ----------- -------------- -------------- 20 DEPT DEPTNO 20 EMP DEPTNO 20 EMP HIREDATE 20 SALGRADE HISAL 20 SALGRADE LOSAL SQL>
-
==============================
6.나는이 같은 (생성 당신이 필요로하는 모든 선택을) 할 것입니다. 당신은 나중에 SQLPLUS에게 공급할 수 :
나는이 같은 (생성 당신이 필요로하는 모든 선택을) 할 것입니다. 당신은 나중에 SQLPLUS에게 공급할 수 :
echo "select table_name from user_tables;" | sqlplus -S user/pwd | grep -v "^--" | grep -v "TABLE_NAME" | grep "^[A-Z]" | while read sw; do echo "desc $sw" | sqlplus -S user/pwd | grep -v "\-\-\-\-\-\-" | awk -F' ' '{print $1}' | while read nw; do echo "select * from $sw where $nw='val'"; done; done;
그것은 산출 :
select * from TBL1 where DESCRIPTION='val' select * from TBL1 where ='val' select * from TBL2 where Name='val' select * from TBL2 where LNG_ID='val'
그리고 그것이 무엇 것은 - USER_TABLES에서 각 TABLE_NAME에 대한 (내림차순)에서 각 필드를 얻을 필드가 '발'에 해당 위치를 테이블에서 선택 *을 만들 수 있습니다.
-
==============================
7.나는 각 테이블에 한 번보다는 빠른 실행을위한 각 테이블의 모든 컬럼에 대한 실행 홍수의 스크립트를 수정했습니다. 그것은 오라클 11g 이상이 필요합니다.
나는 각 테이블에 한 번보다는 빠른 실행을위한 각 테이블의 모든 컬럼에 대한 실행 홍수의 스크립트를 수정했습니다. 그것은 오라클 11g 이상이 필요합니다.
set serveroutput on size 100000 declare v_match_count integer; v_counter integer; -- The owner of the tables to search through (case-sensitive) v_owner varchar2(255) := 'OWNER_NAME'; -- A string that is part of the data type(s) of the columns to search through (case-insensitive) v_data_type varchar2(255) := 'CHAR'; -- The string to be searched for (case-insensitive) v_search_string varchar2(4000) := 'FIND_ME'; -- Store the SQL to execute for each table in a CLOB to get around the 32767 byte max size for a VARCHAR2 in PL/SQL v_sql clob := ''; begin for cur_tables in (select owner, table_name from all_tables where owner = v_owner and table_name in (select table_name from all_tab_columns where owner = all_tables.owner and data_type like '%' || upper(v_data_type) || '%') order by table_name) loop v_counter := 0; v_sql := ''; for cur_columns in (select column_name from all_tab_columns where owner = v_owner and table_name = cur_tables.table_name and data_type like '%' || upper(v_data_type) || '%') loop if v_counter > 0 then v_sql := v_sql || ' or '; end if; v_sql := v_sql || 'upper(' || cur_columns.column_name || ') like ''%' || upper(v_search_string) || '%'''; v_counter := v_counter + 1; end loop; v_sql := 'select count(*) from ' || cur_tables.table_name || ' where ' || v_sql; execute immediate v_sql into v_match_count; if v_match_count > 0 then dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records'); end if; end loop; exception when others then dbms_output.put_line('Error when executing the following: ' || dbms_lob.substr(v_sql, 32600)); end; /
-
==============================
8.우리는 테이블 및 열 이름을 알고 있지만 시간 문자열의 번호를 찾으려면 각 스키마 나타나고있다 :
우리는 테이블 및 열 이름을 알고 있지만 시간 문자열의 번호를 찾으려면 각 스키마 나타나고있다 :
Declare owner VARCHAR2(1000); tbl VARCHAR2(1000); cnt number; ct number; str_sql varchar2(1000); reason varchar2(1000); x varchar2(1000):='%string_to_be_searched%'; cursor csr is select owner,table_name from all_tables where table_name ='table_name'; type rec1 is record ( ct VARCHAR2(1000)); type rec is record ( owner VARCHAR2(1000):='', table_name VARCHAR2(1000):=''); rec2 rec; rec3 rec1; begin for rec2 in csr loop --str_sql:= 'select count(*) from '||rec.owner||'.'||rec.table_name||' where CTV_REMARKS like '||chr(39)||x||chr(39); --dbms_output.put_line(str_sql); --execute immediate str_sql execute immediate 'select count(*) from '||rec2.owner||'.'||rec2.table_name||' where column_name like '||chr(39)||x||chr(39) into rec3; if rec3.ct <> 0 then dbms_output.put_line(rec2.owner||','||rec3.ct); else null; end if; end loop; end;
-
==============================
9.나는 @Lalit Kumars 답변에 대한 다음과 같은 문제가되었다
나는 @Lalit Kumars 답변에 대한 다음과 같은 문제가되었다
ORA-19202: Error occurred in XML processing ORA-00904: "SUCCESS": invalid identifier ORA-06512: at "SYS.DBMS_XMLGEN", line 288 ORA-06512: at line 1 19202. 00000 - "Error occurred in XML processing%s" *Cause: An error occurred when processing the XML function *Action: Check the given error message and fix the appropriate problem
해결 방법은 다음과 같습니다
WITH char_cols AS (SELECT /*+materialize */ table_name, column_name FROM cols WHERE data_type IN ('CHAR', 'VARCHAR2')) SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword", SUBSTR (table_name, 1, 14) "Table", SUBSTR (column_name, 1, 14) "Column" FROM char_cols, TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select "' || column_name || '" from "' || table_name || '" where upper("' || column_name || '") like upper(''%' || :val || '%'')' ).extract ('ROWSET/ROW/*') ) ) t ORDER BY "Table" /
-
==============================
10.절차는 전체 데이터베이스를 검색 :
절차는 전체 데이터베이스를 검색 :
CREATE or REPLACE PROCEDURE SEARCH_DB(SEARCH_STR IN VARCHAR2, TAB_COL_RECS OUT VARCHAR2) IS match_count integer; qry_str varchar2(1000); CURSOR TAB_COL_CURSOR IS SELECT TABLE_NAME,COLUMN_NAME,OWNER,DATA_TYPE FROM ALL_TAB_COLUMNS WHERE DATA_TYPE in ('NUMBER','VARCHAR2') AND OWNER='SCOTT'; BEGIN FOR TAB_COL_REC IN TAB_COL_CURSOR LOOP qry_str := 'SELECT COUNT(*) FROM '||TAB_COL_REC.OWNER||'.'||TAB_COL_REC.TABLE_NAME|| ' WHERE '||TAB_COL_REC.COLUMN_NAME; IF TAB_COL_REC.DATA_TYPE = 'NUMBER' THEN qry_str := qry_str||'='||SEARCH_STR; ELSE qry_str := qry_str||' like '||SEARCH_STR; END IF; --dbms_output.put_line( qry_str ); EXECUTE IMMEDIATE qry_str INTO match_count; IF match_count > 0 THEN dbms_output.put_line( qry_str ); --dbms_output.put_line( TAB_COL_REC.TABLE_NAME ||' '||TAB_COL_REC.COLUMN_NAME ||' '||match_count); TAB_COL_RECS := TAB_COL_RECS||'@@'||TAB_COL_REC.TABLE_NAME||'##'||TAB_COL_REC.COLUMN_NAME; END IF; END LOOP; END SEARCH_DB;
문을 실행
DECLARE SEARCH_STR VARCHAR2(200); TAB_COL_RECS VARCHAR2(200); BEGIN SEARCH_STR := 10; SEARCH_DB( SEARCH_STR => SEARCH_STR, TAB_COL_RECS => TAB_COL_RECS ); DBMS_OUTPUT.PUT_LINE('TAB_COL_RECS = ' || TAB_COL_RECS); END;
샘플 결과
Connecting to the database test. SELECT COUNT(*) FROM SCOTT.EMP WHERE DEPTNO=10 SELECT COUNT(*) FROM SCOTT.DEPT WHERE DEPTNO=10 TAB_COL_RECS = @@EMP##DEPTNO@@DEPT##DEPTNO Process exited. Disconnecting from the database test.
-
==============================
11.코드를 수정하는 경우 소문자를 구별 유사한 쿼리를 사용하는 대신 정확히 일치를 찾는 검색 할 수 ...
코드를 수정하는 경우 소문자를 구별 유사한 쿼리를 사용하는 대신 정확히 일치를 찾는 검색 할 수 ...
DECLARE match_count INTEGER; -- Type the owner of the tables you want to search. v_owner VARCHAR2(255) :='USER'; -- Type the data type you're looking for (in CAPS). Examples include: VARCHAR2, NUMBER, etc. v_data_type VARCHAR2(255) :='VARCHAR2'; -- Type the string you are looking for. v_search_string VARCHAR2(4000) :='Test'; BEGIN dbms_output.put_line( 'Starting the search...' ); FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||t.table_name||' WHERE LOWER('||t.column_name||') LIKE :1' INTO match_count USING LOWER('%'||v_search_string||'%'); IF match_count > 0 THEN dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count ); END IF; END LOOP; END;
-
==============================
12.나는 SQL의 promprt에 대한 간단한 솔루션으로하지 않습니다. Howeve가 사용자 캔 입력이 문자열을 검색 할 수있는 GUI가 두꺼비와 PL / SQL 개발자와 같은 꽤 몇 가지 도구가 있으며 이것이 발견 된 테이블 / 절차 / 객체를 반환합니다.
나는 SQL의 promprt에 대한 간단한 솔루션으로하지 않습니다. Howeve가 사용자 캔 입력이 문자열을 검색 할 수있는 GUI가 두꺼비와 PL / SQL 개발자와 같은 꽤 몇 가지 도구가 있으며 이것이 발견 된 테이블 / 절차 / 객체를 반환합니다.
-
==============================
13.예를 들어, 검색의 이러한 종류를 만드는 몇 가지 무료 도구가 있습니다,이 잘 작동하고 소스 코드를 사용할 수 있습니다 : https://sites.google.com/site/freejansoft/dbsearch
예를 들어, 검색의 이러한 종류를 만드는 몇 가지 무료 도구가 있습니다,이 잘 작동하고 소스 코드를 사용할 수 있습니다 : https://sites.google.com/site/freejansoft/dbsearch
당신은 Oracle ODBC 드라이버와이 도구를 사용하는 DSN 필요합니다.
-
==============================
14.--it가 완료되지 실행 - 오류를
--it가 완료되지 실행 - 오류를
SET SERVEROUTPUT ON SIZE 100000 DECLARE v_match_count INTEGER; v_counter INTEGER; v_owner VARCHAR2 (255) := 'VASOA'; v_search_string VARCHAR2 (4000) := '99999'; v_data_type VARCHAR2 (255) := 'CHAR'; v_sql CLOB := ''; BEGIN FOR cur_tables IN ( SELECT owner, table_name FROM all_tables WHERE owner = v_owner AND table_name IN (SELECT table_name FROM all_tab_columns WHERE owner = all_tables.owner AND data_type LIKE '%' || UPPER (v_data_type) || '%') ORDER BY table_name) LOOP v_counter := 0; v_sql := ''; FOR cur_columns IN (SELECT column_name, table_name FROM all_tab_columns WHERE owner = v_owner AND table_name = cur_tables.table_name AND data_type LIKE '%' || UPPER (v_data_type) || '%') LOOP IF v_counter > 0 THEN v_sql := v_sql || ' or '; END IF; IF cur_columns.column_name is not null THEN v_sql := v_sql || 'upper(' || cur_columns.column_name || ') =''' || UPPER (v_search_string)||''''; v_counter := v_counter + 1; END IF; END LOOP; IF v_sql is null THEN v_sql := 'select count(*) from ' || v_owner || '.' || cur_tables.table_name; END IF; IF v_sql is not null THEN v_sql := 'select count(*) from ' || v_owner || '.' || cur_tables.table_name || ' where ' || v_sql; END IF; --v_sql := 'select count(*) from ' ||v_owner||'.'|| cur_tables.table_name ||' where '|| v_sql; --dbms_output.put_line(v_sql); --DBMS_OUTPUT.put_line (v_sql); EXECUTE IMMEDIATE v_sql INTO v_match_count; IF v_match_count > 0 THEN DBMS_OUTPUT.put_line (v_sql); dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records'); END IF; END LOOP; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line ( 'Error when executing the following: ' || DBMS_LOB.SUBSTR (v_sql, 32600)); END; /
-
==============================
15.약간 강화하고 다음과 같은 간단한 SQL 문이 아주 잘 일을 할 것이 블로그 게시물에서 간단하게 대출 :
약간 강화하고 다음과 같은 간단한 SQL 문이 아주 잘 일을 할 것이 블로그 게시물에서 간단하게 대출 :
SELECT DISTINCT (:val) "Search Value", TABLE_NAME "Table", COLUMN_NAME "Column" FROM cols, TABLE (XMLSEQUENCE (DBMS_XMLGEN.GETXMLTYPE( 'SELECT "' || COLUMN_NAME || '" FROM "' || TABLE_NAME || '" WHERE UPPER("' || COLUMN_NAME || '") LIKE UPPER(''%' || :val || '%'')' ).EXTRACT ('ROWSET/ROW/*'))) ORDER BY "Table";
from https://stackoverflow.com/questions/208493/search-all-fields-in-all-tables-for-a-specific-value-oracle by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 한 성명에서 자바 실행 여러 개의 쿼리 (0) | 2020.03.09 |
---|---|
[SQL] 어떻게 마지막으로 삽입 된 ID를 얻는 방법? (0) | 2020.03.09 |
[SQL] MySQL의에 그렇지 않은 경우 (일명 "upsert"또는 "병합")을 삽입있는 경우 어떻게 업데이트하나요? (0) | 2020.03.09 |
[SQL] 오라클 SQL은 : 다른 테이블의 데이터로 테이블을 업데이트 (0) | 2020.03.09 |
[SQL] 사용하여 SQL 업데이트 쿼리 조인 (0) | 2020.03.09 |