我寫低於所存儲的程序被移動到服務器(「DIR」文件夾)的一種讀取逗號分隔的文件的目的,並且當腳本被執行,它基本上解析文件(.csv),並將數據分配給其各自的變量(xJOB_ID,xCTRL_ID,xACCT_SEC,xCREATEDON_DATE),以便我可以將數據插入到表中。
我在Windows 7環境中使用Oracle SQL Developer版本4.0.0.13。幸運的是,在我的頭上敲了幾下代碼後,我的腳本沒有任何問題。該文件的
如何優化子&instring或替代功能用於調試
實施例的格式:
1111,2,T,10/10/2000
2222,12345,U,10/10/2001
5555,123,S,10/10/1999
我的問題: 我發現了一個小的難度使用SUBSTRING & INSTRING功能來分析數據,並想知道我怎麼能提高日e腳本,以便在需要調試的情況下,可以輕鬆解決未編寫存儲過程的人員的問題。
請讓我知道,如果這是有道理的。我給了你整個腳本,以便你能夠理解我正在努力完成的任務,並且爲了調試目的我可以改進代碼。
create or replace PROCEDURE SP_INSERT_INTO_TABLE(xFILE_NAME IN VARCHAR2)
IS
--UTL_FILE is an oracle package that allows you to read and write operating system files.
TEXT_DATA UTL_FILE.FILE_TYPE;
v_ROW_LENGTH NUMBER := 1024;
v_TEXTSTRING VARCHAR2(4000);
cLINE VARCHAR2(100);
xJOB_ID NUMBER;
xCTRL_ID NUMBER;
xACCT_SEC VARCHAR2(1);
xCREATEDON_DATE DATE;
xCOUNT NUMBER := 0;
BEGIN
BEGIN
--Streams in the file data and assigns it to TEXT_DATA variable.
TEXT_DATA := UTL_FILE.FOPEN('DIR', xFILE_NAME, 'R', v_ROW_LENGTH);
END;
--Begin LOOP to get each line and assign to cLINE to extract, assign to each variable, and insert into the table
LOOP
BEGIN
--Gets each string/line up to the line terminator
UTL_FILE.GET_LINE(TEXT_DATA, v_TEXTSTRING);
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
--Each line is assigned to the variable cLINE.
cLINE := v_TEXTSTRING;
--Begin to parse data using SUBSTRING and INSTRING functions
BEGIN
--Extracts string from cLINE position 1 up to the first occurrence, converts it to a number, and assigns it to the variable.
xJOB_ID := TO_NUMBER(SUBSTR(cLINE, 1,INSTR(cLINE, ',', 1, 1)-1));
--Extracts string from cLINE between the 1st and 2nd occurrence, converts it to a number, and assigns it to the variable.
xCTRL_ID := TO_NUMBER(SUBSTR(cLINE, INSTR(cLINE, ',', 1, 1)+1, INSTR(cLINE, ',', 1,2)-INSTR(cLINE, ',', 1,1)-1));
--Extracts string from cLINE between the 2nd and 3rd occurrence and assigns it to the variable.
xACCT_SEC := SUBSTR(cLINE, INSTR(cLINE, ',', 1, 2) +1, INSTR(cLINE, ',', 1,3)-INSTR(cLINE, ',', 1,2) -1);
--Extracts string from cLINE after the last occurrence, converts it to a date, and assigns it the variable.
xCREATEDON_DATE := TO_DATE(SUBSTR(cLINE, INSTR(cLINE, ',', 1, 3)+1), 'MM/DD/YYYY');
INSERT INTO TABLE(JOB_ID, CTRL_ID, ACCT_SEC, CREATEDON_DATE)
VALUES(xJOB_ID, xCTRL_ID, xACCT_SEC, xCREATEDON_DATE);
COMMIT;
--Counter to count the amount of inserts
xCOUNT := xCOUNT + 1;
EXCEPTION
--Exception to handle the conversion of a string to a NUMBER or value is longer than the declared length of the variable.
WHEN VALUE_ERROR THEN
NULL;
END;
END LOOP;
DBMS_OUTPUT.PUT_LINE('RECORDS INSERTED: ' || xCOUNT);
UTL_FILE.FCLOSE(TEXT_DATA);
END;
是否有你創建自己的解決方案的原因,而不是使用[SQL \ * Loader](https://docs.oracle.com/cd/E11882_01/server.112/e22490/ldr_concepts.htm)或者[外部表](https://docs.oracle.com/cd/E11882_01/server.112/e22490/et_concepts.htm)將文件加載到表中?該文件已存在於服務器上並位於已識別的目錄中,因此外部表似乎是最簡單的方法。 –
@AlexPoole - 說實話,沒有意識到SQL * Loader,不知道我將如何使用它,我確實想到了一個外部表,但是當我運行'SELECT * FROM EXTERNAL_TABLE'時,似乎遇到了問題.CSV文件(也許我會盡快解決這個問題,並將我的腦袋多一點)。我是否因使用SP而讓自己的生活變得艱難?謝謝! – NewComer
優秀點,@AlexPoole!外部桌子FTW! \ o /(插入變成insert into table_name(...)select ... from external_table_name;'這真的很容易調試......) – Boneist