情况是向表中插入一行,其中一列是 BLOB。 BLOB 是从文件中读取的,并且在插入新行时工作正常。这是用于执行 INSERT 的代码:
DECLARE
l_dir VARCHAR2(20) := 'TEMP_DIRECTORY';
l_file VARCHAR2(20) := 'AAPL.pdf';
l_bfile BFILE;
l_blob BLOB;
BEGIN
INSERT INTO article_history (ticker, date_published, pdf_report)
VALUES ('AAPL', SYSDATE, EMPTY_BLOB())
RETURN pdf_report INTO l_blob;
l_bfile := BFILENAME(l_dir, l_file);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
DBMS_LOB.loadfromfile(l_blob, l_bfile, DBMS_LOB.getlength(l_bfile));
DBMS_LOB.fileclose(l_bfile);
COMMIT;
END;
/
但是 BLOB 列在插入时并未填充,稍后会更新。所以,我的问题是:如何检索 LOB 定位器并使用文件中的内容更新 BLOB 列?
不知道如何编写代码来做到这一点。
与使用
INSERT
执行完全相同的操作,但使用 SELECT
来获取 BLOB 句柄,而不是 INSERT ... RETURNING ... INTO ...
DECLARE
l_dir VARCHAR2(20) := 'TEMP_DIRECTORY';
l_file VARCHAR2(20) := 'AAPL.pdf';
l_bfile BFILE;
l_blob BLOB;
BEGIN
SELECT pdf_report
INTO l_blob
FROM article_history
WHERE ticker = 'AAPL';
l_bfile := BFILENAME(l_dir, l_file);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
DBMS_LOB.loadfromfile(l_blob, l_bfile, DBMS_LOB.getlength(l_bfile));
DBMS_LOB.fileclose(l_bfile);
COMMIT;
END;
/
一种选择是创建一个读取文件并返回 BLOB 的函数。这样您就可以在需要插入/更新表的 BLOB 列时使用它。
FUNCTION FILE2BLOB (mDir IN VARCHAR2,
mFileName IN VARCHAR2) RETURN BLOB
IS
BEGIN
Declare
mBLOB BLOB := Empty_Blob();
mBinFile BFILE := BFILENAME(mDir, mFileName);
Begin
DBMS_LOB.OPEN(mBinFile, DBMS_LOB.LOB_READONLY); -- Open BFILE
DBMS_LOB.CreateTemporary(mBLOB, TRUE, DBMS_LOB.Session); -- BLOB locator initialization
DBMS_LOB.OPEN(mBLOB, DBMS_LOB.LOB_READWRITE); -- Open BLOB locator for writing
DBMS_LOB.LoadFromFile(mBLOB, mBinFile, DBMS_LOB.getLength(mBinFile)); -- Reading BFILE into BLOB
DBMS_LOB.CLOSE(mBLOB); -- Close BLOB locator
DBMS_LOB.CLOSE(mBinFile); -- Close BFILE
RETURN mBLOB; -- Return BLOB
End;
END FILE2BLOB;
将 BLOB 插入表列...
Insert Into article_history (ticker, date_published, pdf_report)
VALUES ( 'AAPL', SYSDATE, FILE2BLOB('your_directory_obj', 'your_file_name') );
更新表的 BLOB 列...
Update your_table_name
Set your_blob_column = FILE2BLOB('your_directory_obj', 'your_file_name')
Where your_pk_column = PK_VALUE;