Oracle로 변환 할 수 있는지 확인해야하는 쿼리가 있습니다.
WITH Cte
AS (SELECT cast('<S>' + replace(replace(N'$(AppServers)', ';', ','), ',', '</S><S>') + '</S>' AS XML) AS Servers)
INSERT INTO INSTANCE
(INSTANCE_ID,
SERVER_NAME,
INSTANCE_IDENTIFIER,
IDENTIFIER_PREFIX)
SELECT ROW_NUMBER() OVER (ORDER BY SERVER_NAME) - 1,
SERVER_NAME,
NULL,
0
FROM (SELECT DISTINCT upper(Split.Server.value('.', 'VARCHAR(100)')) AS SERVER_NAME
FROM Cte
CROSS apply Servers.nodes('/S') Split(Server)) Servers
ORDER BY SERVER_NAME;
Oracle 11g가 XML을 전담 지원한다는 것을 알고 있지만이 문제를 해결할 방법을 찾을 수 없습니다. 어떤 도움이라도 대단히 감사합니다.
위의 쿼리 $(AppServers)
는가로 바뀌면 다음을 삽입합니다 foo,bar;baz,wibble
.
+-------------+-------------+---------------------+-------------------+
| INSTANCE_ID | SERVER_NAME | INSTANCE_IDENTIFIER | IDENTIFIER_PREFIX |
+-------------+-------------+---------------------+-------------------+
| 0 | BAR | NULL | 0 |
| 1 | BAZ | NULL | 0 |
| 2 | FOO | NULL | 0 |
| 3 | WIBBLE | NULL | 0 |
+-------------+-------------+---------------------+-------------------+
XML 코드는 구분 된 (쉼표 또는 세미콜론으로) 문자열을 행으로 분할하기위한 것입니다. 그런 다음 값은 대문자로 표시되고 중복 항목이 제거 된 다음 알파벳순으로 정렬되어 Instance_Id를 가져옵니다.
dbforums.com의 @LKBrwn_DBA가 이에 대한 해결책을 마련했습니다.
CREATE OR REPLACE TYPE Csvparserreturn AS TABLE OF VARCHAR2 ( 4000 );
/
CREATE OR REPLACE FUNCTION Csvparser ( P_Dat IN CLOB, P_Hdr IN VARCHAR2 )
RETURN Csvparserreturn
AS
L_Debug CHAR ( 1 ) := 'F';
L_Hdr VARCHAR2 ( 4000 );
L_Dat CLOB;
L_Wrk CLOB;
L_Recsep CHAR ( 1 ) := CHR ( 9 );
O_Hdr VARCHAR2 ( 4000 );
O_Dat CLOB;
O_Data_Tab Csvparserreturn := Csvparserreturn ( );
TYPE Text_Array IS TABLE OF VARCHAR2 ( 4000 )
INDEX BY PLS_INTEGER;
L_Hdr_Array Text_Array;
L_Dat_Array Text_Array;
L_Fld_Array Text_Array;
L_Elm_Array Text_Array;
L_Val_Array Text_Array;
L_Hdr_Count PLS_INTEGER;
L_Dat_Count PLS_INTEGER;
L_Fld_Count PLS_INTEGER;
I PLS_INTEGER;
J PLS_INTEGER;
K PLS_INTEGER;
L PLS_INTEGER;
N PLS_INTEGER;
PROCEDURE Print_Line ( P_Text VARCHAR2 )
IS
BEGIN
IF L_Debug = 'T'
THEN
DBMS_OUTPUT.Put_Line ( P_Text );
END IF;
END;
FUNCTION Parse_Csv ( P_Text CLOB, P_Delim VARCHAR2 DEFAULT ',' )
RETURN Text_Array
IS
Wk_Array Text_Array;
BEGIN
N := 1;
L := 1;
K := 1;
WHILE 1 = 1
LOOP
L := INSTR ( SUBSTR ( P_Text || P_Delim, K + 1 )
, P_Delim );
EXIT WHEN K >= LENGTH ( P_Text );
Wk_Array ( N ) := SUBSTR ( P_Text, K, L );
N := N + 1;
K := K + L + 1;
END LOOP;
RETURN Wk_Array;
END;
BEGIN
L_Hdr := P_Hdr;
L_Dat := P_Dat;
L_Hdr_Array := Parse_Csv ( L_Hdr );
L_Hdr_Count := L_Hdr_Array.COUNT;
Print_Line ( 'Hdr#' || L_Hdr_Count );
O_Hdr := '';
FOR I IN 1 .. L_Hdr_Count
LOOP
O_Hdr := O_Hdr || L_Hdr_Array ( I ) || L_Recsep;
Print_Line ( 'Elm#' || I || ': ' || L_Hdr_Array ( I ) );
END LOOP;
L_Wrk := SUBSTR ( L_Dat, 2, LENGTH ( L_Dat ) - 2 );
SELECT REPLACE ( L_Wrk, '),(', L_Recsep ) || L_Recsep INTO L_Wrk FROM DUAL;
Print_Line ( 'Dat: ' || L_Wrk );
L_Dat_Array := Parse_Csv ( L_Wrk, L_Recsep );
L_Dat_Count := L_Dat_Array.COUNT;
O_Data_Tab.EXTEND;
O_Data_Tab ( 1 ) := O_Hdr;
FOR I IN 1 .. L_Dat_Count
LOOP
L_Fld_Array := Parse_Csv ( L_Dat_Array ( I ) );
L_Fld_Count := L_Fld_Array.COUNT;
Print_Line ( 'Rec#' || I || ': ' || L_Dat_Array ( I ) || ' Flds:' || L_Fld_Count );
O_Dat := '';
FOR J IN 1 .. L_Hdr_Count
LOOP
K := 0;
FOR N IN 1 .. L_Fld_Count
LOOP
IF L_Hdr_Array ( J ) =
SUBSTR ( L_Fld_Array ( N )
, 1, LENGTH ( L_Hdr_Array ( J ) ) )
THEN
K := N;
CONTINUE;
END IF;
END LOOP;
IF K > 0
THEN
L := INSTR ( L_Fld_Array ( K ), '=' );
L_Elm_Array ( J ) := SUBSTR ( L_Fld_Array ( K ), 1, L - 1 );
L_Val_Array ( J ) := SUBSTR ( L_Fld_Array ( K ), L + 1 );
ELSE
L_Elm_Array ( J ) := '#N/A';
L_Val_Array ( J ) := '#N/A';
END IF;
Print_Line ( 'Element ' || TO_CHAR ( J ) || '.' || L_Hdr_Array ( J ) || '=' || L_Val_Array ( J ) );
O_Dat := O_Dat || L_Val_Array ( J ) || L_Recsep;
END LOOP;
Print_Line ( 'Out#' || TO_CHAR ( I ) || '=' || O_Dat );
O_Data_Tab.EXTEND;
O_Data_Tab ( I + 1 ) := O_Dat;
END LOOP;
RETURN O_Data_Tab;
END;
/
사용법은 다음과 같습니다.
DECLARE
Out_Data Csvparserreturn := Csvparserreturn ( );
X_Hdr VARCHAR2 ( 4000 ) := 'Directory,ID,Location,UserName,Password,Selector';
X_Dat CLOB := '(Directory=Voice Active Directory A,ID=VT-AD1,Location=Canada,UserName=admin,Password=passw0rd,Selector=AD1),(Directory=Voice Active Directory B,ID=VT-AD2,Location=https://beta-proxy.voice.com/VTadp/Proxy/[/url],UserName=admin,Password=passw0rd,Selector=AD2),(Directory=Voice Active Directory C,ID=VT-AD3,Location=https://final-proxy.voice.com/VTadp/Proxy/,UserName=admin,Password=passw0rd)';
BEGIN
Out_Data := Csvparser ( X_Dat, X_Hdr );
FOR I IN Out_Data.FIRST .. Out_Data.LAST
LOOP
DBMS_OUTPUT.Put_Line ( 'Rec# ' || TO_CHAR ( I, 'FM000.' ) || Out_Data ( I ) );
END LOOP;
END;
/
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다