我写低于所存储的程序被移动到服务器(“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