Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Đọc và nhập tệp CSV trong Oracle PL / SQL một cách hiệu quả

Ví dụ dưới đây để đọc và nhập CSV tệp (được phân cách bằng dấu phẩy) trong PLSQL. Có một gói trong các biểu mẫu Oracle "D2k_Delimited_String" chúng tôi sử dụng để đọc và nhập tệp được phân tách bằng dấu phẩy (hoặc bất kỳ dấu phân tách nào), tôi đã viết một bài trên Oracle Forms để đọc các tệp được phân tách bằng gói này, sau đây là liên kết https:/ /www.foxinfotech.in/2013/02/reading-and-importing-comma-delimited.html. Cùng một gói mà tôi đã chuyển đổi thành gói cơ sở dữ liệu để đọc tệp CSV trong PLSQL một cách hiệu quả, tôi đã đổi tên gói thành "Plsql_Delimited_String". Dưới đây là một ví dụ được đưa ra để nhập tệp csv trong PL SQL với sự trợ giúp của hàm gói này Get_String, sau đây là cách sử dụng hàm này:

Plsql_Delimited_String.Getstring ([chuỗi chứa văn bản được phân tách, toàn bộ hàng],
[comburance],
[unter end boolean default false],
[Delimeter]);

Trong quy trình sau, người dùng sẽ chuyển một tên tệp phải có trong vị trí thư mục được tạo trong đối tượng thư mục Oracle, trong ví dụ này đối tượng thư mục 'YOUR_DIRECTORY' được sử dụng, thay đổi nó bằng đối tượng thư mục của bạn và sao chép tệp được phân tách ở vị trí đó rồi chuyển tên tệp cho thủ tục này.

TẠO HOẶC THAY THẾ THỦ TỤC Import_Emp_File (P_FILENAME IN VARCHAR2,
o_msg OUT VARCHAR2)
IS
Infile UTL_FILE.File_Type;
Linebuf VARCHAR2 (4000);
V_Getstring VARCHAR2 (100 );

- Mảng giá trị trường
LOẠI Giá trị trường LÀ BẢNG CỦA VARCHAR2 (100)
INDEX BY BINARY_INTEGER;

Field_Position Fieldvalue;

Total_Rec_Count NUMBER:=0;
Total_Rec_Processed NUMBER:=0;
BEGIN
Infile:=UTL_FILE.Fopen ('YOUR_DIRECTORY', P_FILENAME, 'R');

LOOP
---
UTL_FILE.Get_Line (Infile, Linebuf);
- thêm dấu gạch ngang ở cuối dòng để đọc tất cả các trường

Linebuf:=Linebuf || '|';

- Giả sử tệp chứa Sáu chuỗi phân tách bằng dấu ngoặc kép (|)
FOR I IN 1 .. 6
LOOP
Field_Position (I):=
Plsql_Delimited_String.Getstring (Linebuf ,
I,
FALSE,
'|');
KẾT THÚC ĐĂNG NHẬP;

BEGIN
Total_Rec_Count:=Total_Rec_Count + 1;

- một bảng mẫu
INSERT INTO EMP (EMPLOYEE_NUMBER,
FIRST_NAME,
LAST_NAME,
DATE_OF_JOIN,
EMP_TYPE,
DATE_OF_REGN)
GIÁ TRỊ (field_position (1),
field_position (2),
field_position (3),
field_position (4),
field_position (5),
field_position (6) );

Total_Rec_Processed:=Total_Rec_Processed + 1;
NGOẠI LỆ
KHI NGƯỜI KHÁC
THÌ
- bỏ qua lỗi trong quá trình chèn cơ sở dữ liệu
NULL;
HẾT;
KẾT THÚC ĐĂNG NHẬP;

IF UTL_FILE.is_open (infile)
THÌ
UTL_FILE.Fclose (Infile);
HẾT IF;
NGOẠI LỆ
KHI KHÔNG CÓ_DATA_FOUND
THÌ
IF UTL_FILE.is_open (infile)
THÌ
UTL_FILE.Fclose (Infile);
HẾT IF;

IF total_rec_processed> 0
THEN
COMMIT;
HẾT IF;
KHI NGƯỜI KHÁC
THÌ
IF UTL_FILE.is_open (infile)
THEN
UTL_FILE.Fclose (Infile);
HẾT IF;

o_msg:=SQLERRM;
END;
/ Sau đây là nguồn gói của PLSQL_DELIMITED_STRING được sử dụng trong ví dụ này, hãy cài đặt gói này trong lược đồ của bạn. Gói chứa nhiều hàm tiện ích khác có thể được sử dụng để đọc tệp csv bằng PLSQL:

TẠO HOẶC THAY THẾ GÓI plsql_Delimited_String IS

function Counter (Source_string trong varchar2,
UnTermina in Boolean default FALSE,
Delimiter in varchar2 default ',') return number;
Thủ tục PutString (Source_string trong varchar2,
String_to_add in varchar2,
Field_position in number,
UnTermina in Boolean default FALSE,
Delimiter in varchar2 default ',');
Thủ tục PutNumber (Chuỗi nguồn trong varchar2,
number_to_add theo số,
Field_position trong số,
Bỏ kết thúc trong Boolean mặc định FALSE,
Dấu phân cách trong varchar2 default ',');
Thủ tục PutDate (Chuỗi nguồn trong varchar2,
Date_to_add in date,
Field_position in number,
UnTer End in Bo olean default FALSE,
Dấu tách trong varchar2 default ',');
hàm GetString (Source_string trong varchar2,
Field_position in number,
UnTermina in Boolean default FALSE,
Dấu tách trong varchar2 default ',') trả về varchar2;
hàm GetNumber (Chuỗi nguồn trong varchar2,
Field_position trong số,
Bỏ kết thúc trong Boolean mặc định FALSE,
Dấu phân cách trong varchar2 mặc định ', ') return number;
function GetDate (Source_string in varchar2,
Field_position in number,
UnTermina in Boolean default FALSE,
Delimiter in varchar2 default', ') return date;
function Định vị (Source_string trong varchar2,
Search_String trong varchar2,
UnTermina trong Boole một FALSE mặc định,
Dấu phân cách trong varchar2 default ',') trả về số;
hàm Định vị (Chuỗi nguồn trong varchar2,
Tìm kiếm_date trong ngày,
Bỏ kết thúc trong Boolean mặc định FALSE,
Dấu phân cách trong varchar2 default ',') trả về số;
hàm Định vị (Chuỗi nguồn trong varchar2,
Tìm kiếm_number trong số,
Bỏ kết thúc trong Boolean mặc định FALSE,
Dấu phân cách trong varchar2 mặc định ',') trả về số;
HẾT plsql_Delimited_String;
/

TẠO HOẶC THAY THẾ GÓI CƠ THỂ plsql_Delimited_String
IS
FUNCTION Counter (Source_string IN VARCHAR2,
UnTermination in BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
SỐ TRỞ LẠI
IS
iModifier PLS_INTEGER:=0;
iOldSize PLS_INTEGER:=LENGTH (Source_string);
BẮT ĐẦU
NẾU Chưa kết thúc
THEN
iModifier:=1;
HẾT NẾU;

RETURN (iOldSize - LENGTH (REPLACE (Source_string, Delimiter)))
+ iModifier;
END Counter;

QUY TRÌNH ĐẶT Chuỗi đặt (chuỗi nguồn VÀO VARCHAR2,
chuỗi_to_add TRONG VARCHAR2,
vị trí trường trong số,
không kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
IS
iStrLen PLS_INTEGER:=LENGTH (Source_String);
iStrFragLen PLS_INTEGER:=LENGTH (String_to_add);
iPtrStart PLS_INTEGER:=0;
iPtrEnd PLS_INTEGER:=0;
vcSepBuffer VARCHAR2 (2000);
iCounter PLS_INTEGER;
BEGIN
- 1. là chuỗi Zero Length?
IF iStrLen =0
THEN
IF Field_Position> 1
THÌ
ĐỐI VỚI iCounter TRONG 2 .. Field_Position
LOOP
vcSepBuffer:=vcSepBuffer || Dấu phân cách;
KẾT THÚC LOOP;
KẾT THÚC NẾU;

Source_string:=vcSepBuffer || String_to_add;

NẾU KHÔNG phải là chưa kết thúc
THÌ
Source_string:=Source_String || Dấu phân cách;
iStrLen:=LENGTH (Chuỗi nguồn);
KẾT THÚC IF;
ELSE
- 2. Làm việc với chuỗi chưa kết thúc
IF UnTermina
THEN
Source_string:=Source_string || Dấu phân cách;
KẾT THÚC NẾU;

- 3. Định vị dấu phân cách thứ n
IF Field_Position> 1
THEN
LOOP
iPtrStart:=
(INSTR (Source_string || vcSepBuffer,
> Dấu phân cách,
1,
Field_Position - 1)
- 1)
+ LENGTH (Dấu phân cách);
THOÁT KHI iPtrStart> 0;
vcSepBuffer:=vcSepBuffer || Dấu phân cách;
KẾT THÚC LOOP;

NẾU vcSepBuffer KHÔNG ĐẦY ĐỦ
THÌ
iPtrEnd:=iStrLen;
ELSE
iPtrEnd:=
INSTR (Source_string,
Delimiter,
1 ,
Field_Position);

IF iPtrEnd =0
THEN
iPtrEnd:=iStrLen;
KẾT THÚC IF;
KẾT THÚC IF;
ELSE
iPtrStart:=0;
iPtrEnd:=
INSTR (Source_string,
Delimiter,
1,
Field_Position);

IF iPtrEnd =0
THEN
iPtrEnd:=iStrLen;
HẾT IF;
HẾT IF;

- 3. Xây dựng lại chuỗi
Source_string:=
SUBSTR (Source_string, 1, iPtrStart)
|| vcSepBuffer
|| String_to_add
|| Dấu phân cách
|| SUBSTR (Chuỗi nguồn, iPtrEnd + LENGTH (Dấu phân cách));

- 4. Sắp xếp chấm dứt
NẾU Không chấm dứt
THÌ
Source_string:=
SUBSTR (Source_String,
1,
(LENGTH (Source_string) - LENGTH (Dấu phân cách)));
KẾT THÚC IF;
KẾT THÚC IF;
KẾT THÚC PutString;

THỦ TỤC Đặt số (Chuỗi nguồn VÀO RA VARCHAR2,
số_đến_đầu_trong SỐ,
Vị trí trường TRONG SỐ,
Không kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
IS
BEGIN
- 1. Chỉ cần thực hiện chuyển đổi kiểu dữ liệu và gọi varchar2 varsion of put ..
plsql_Delimited_String.PutString (Source_string,
TO_CHAR (number_to_add),
Field_position,
UnTermina,
Delimiter);
END PutNumber;

PROCEDURE PutDate (Chuỗi nguồn VÀO RA VARCHAR2,
Date_to_add TRONG NGÀY,
Field_position TRONG SỐ,
Bỏ kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
IS
BEGIN
- 1. Chỉ cần thực hiện chuyển đổi kiểu dữ liệu và gọi varchar2 varsion of put ..
plsql_Delimited_String.
PutString (Source_string,
TO_CHAR (date_to_add, ' DD-MON-YYYY HH24:MI:SS '),
Field_position,
UnTermina,
Delimiter);
END PutDate;

FUNCTION GetString (Chuỗi nguồn TRONG VARCHAR2,
Field_position TRONG SỐ,
Không kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
RETURN VARCHAR2
IS
iPtrEnd PLS_INTEGER:=0;
iPtrStart PLS_INTEGER:=0;
vcSourceStrCopy VARCHAR2 (2000):=Source_string;
BẮT ĐẦU
NẾU Không được chấm dứt
THÌ
vcSourceStrCopy:=vcSourceStrCopy || Dấu phân cách;
KẾT THÚC NẾU;

IF Field_Position> 1
THEN
iPtrStart:=
INSTR (vcSourceStrCopy,
Delimiter,
1,
Field_Position - 1)
+ LENGTH (Dấu phân cách);
ELSE
iPtrStart:=1;
KẾT THÚC IF;

iPtrEnd:=
INSTR (vcSourceStrCopy,
Dấu phân cách,
1,
Field_Position);
RETURN SUBSTR (vcSourceStrCopy, iPtrStart, (iPtrEnd - iPtrStart));
KẾT THÚC GetString; / * Phiên bản chuỗi * /

FUNCTION GetNumber (Chuỗi nguồn TRONG VARCHAR2,
Field_position TRONG SỐ,
Không kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
SỐ TRẢ LẠI

iRc PLS_INTEGER;
BEGIN
RETURN TO_NUMBER (GetString (Source_string,
Field_Position,
UnTermina,
Delimiter));
END GetNumber; / * Phiên bản số * /

FUNCTION GetDate (Chuỗi nguồn TRONG VARCHAR2,
Field_position TRONG SỐ,
Không kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
NGÀY TRỞ LẠI

BEGIN
RETURN TO_DATE (GetString (Source_string,
Field_Position,
UnTermina,
Delimiter), 'DD-MON-YYYY HH24:MI:SS');
KẾT THÚC GetDate; / * Phiên bản ngày * /

FUNCTION Định vị (Chuỗi nguồn TRONG VARCHAR2,
Chuỗi tìm kiếm TRONG VARCHAR2,
Không kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
SỐ TRẢ LẠI

iHit PLS_INTEGER:=0;
iCounter PLS_INTEGER;
vcCompare VARCHAR2 (2000);
BEGIN
FOR iCounter IN 1 .. Counter (Source_String, UnTermina, Delimiter)
LOOP
IF GetString (Source_String,
iCounter,
UnTermina,
Delimiter) =Search_String
THEN
iHit:=iCounter;
EXIT;
KẾT THÚC NẾU;
KẾT THÚC ĐĂNG NHẬP;

QUAY LẠI iHit;
HẾT Vị trí;

FUNCTION Định vị (Chuỗi nguồn TRONG VARCHAR2,
Search_date TRONG DATE,
Chưa kết thúc TRONG BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
SỐ TRẢ LẠI

BEGIN
QUAY LẠI Vị trí (Chuỗi nguồn,
TO_CHAR (Ngày tìm kiếm, 'DD-MON-YYYY HH24:MI:SS'),
Chưa kết thúc,
Dấu phân cách);
Định vị KẾT THÚC; / * Phiên bản ngày * /

FUNCTION Định vị (Chuỗi nguồn TRONG VARCHAR2,
Search_number TRONG SỐ,
Không kết thúc trong BOOLEAN DEFAULT FALSE,
Dấu phân cách TRONG VARCHAR2 DEFAULT ',')
SỐ TRẢ LẠI

BEGIN
RETURN Định vị (Chuỗi nguồn,
TO_CHAR (Số tìm kiếm),
Chưa kết thúc,
Dấu phân cách);
END Định vị; / * Phiên bản số * /
HẾT; / * Nội dung * /
/

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL không nhận ra bí danh cột trong mệnh đề where

  2. Cách sử dụng rownum

  3. Có thể xảy ra bế tắc khi cập nhật và xóa các hàng khác nhau trong bảng không?

  4. Làm thế nào để Kiểm tra xem tệp có phải là hình ảnh bằng PL / SQL hay không?

  5. Nhân bản các bản ghi để lấp đầy khoảng trống giữa các ngày