【发布时间】:2017-11-12 10:46:06
【问题描述】:
尝试为多行更新 blob 列中的图片,我收到成功的消息,没有错误,但尚未呈现更改。我重新启动了 Oracle 服务和机器,但仍然没有传播。是的,如图所示,我正在提交,但我只尝试了一个 blob 无济于事。
- 它是临时的 dest_lob 对象吗? readonly 类型?我必须释放临时 blob 吗?
- 是否未设置适当的架构?我用架构用户调用它。
- 以前的 blob 内容是否必须是
NULL? Hamlet.jpg 尝试 (ID = 101) 在 Picture blob 列中维护NULL。 - 这是否是 Oracle 的缓存问题?我是否必须刷新表空间文件之类的内容?
- 是多个
BEGIN...END调用吗?
表格
SQL > desc Characters;
Name Null? Type
----------------------------------------------------------------
ID NOT NULL NUMBER(5)
CHARACTER VARCHAR2(255 CHAR)
DESCRIPTION VARCHAR2(1000 CHAR)
SOURCE VARCHAR2(255 CHAR)
QUOTE VARCHAR2(1500 CHAR)
PICTURE BLOB
LINKIMAGE VARCHAR2(255 CHAR)
PL-SQL
CREATE OR REPLACE DIRECTORY MY_DIR AS '/path/to/pictures';
DECLARE
src_bfile BFILE := BFILENAME('MY_DIR', 'HenryCorwin.jpg');
dest_blob BLOB;
BEGIN
SELECT PICTURE into dest_blob FROM CHARACTERS WHERE ID = 44;
DBMS_LOB.OPEN(src_bfile, DBMS_LOB.LOB_READONLY);
DBMS_LOB.CREATETEMPORARY( dest_blob, TRUE);
DBMS_LOB.LoadFromFile( DEST_LOB => dest_blob,
SRC_LOB => src_bfile,
AMOUNT => DBMS_LOB.GETLENGTH(src_bfile) );
DBMS_LOB.CLOSE(src_bfile);
COMMIT;
END;
/
DECLARE
src_bfile BFILE := BFILENAME('MY_DIR', 'Hamlet.jpg');
dest_blob BLOB;
BEGIN
SELECT PICTURE into dest_blob FROM CHARACTERS WHERE ID = 101;
DBMS_LOB.OPEN(src_bfile, DBMS_LOB.LOB_READONLY);
DBMS_LOB.CREATETEMPORARY( dest_blob, TRUE);
DBMS_LOB.LoadFromFile( DEST_LOB => dest_blob,
SRC_LOB => src_bfile,
AMOUNT => DBMS_LOB.GETLENGTH(src_bfile) );
DBMS_LOB.CLOSE(src_bfile);
COMMIT;
END;
/
DECLARE
src_bfile BFILE := BFILENAME('MY_DIR', 'CGreen.jpg');
dest_blob BLOB;
BEGIN
SELECT PICTURE into dest_blob FROM CHARACTERS WHERE ID = 15;
DBMS_LOB.OPEN(src_bfile, DBMS_LOB.LOB_READONLY);
DBMS_LOB.CREATETEMPORARY( dest_blob, TRUE);
DBMS_LOB.LoadFromFile( DEST_LOB => dest_blob,
SRC_LOB => src_bfile,
AMOUNT => DBMS_LOB.GETLENGTH(src_bfile) );
DBMS_LOB.CLOSE(src_bfile);
COMMIT;
END;
/
DECLARE
src_bfile BFILE := BFILENAME('MY_DIR', 'SevenOfNine.jpg');
dest_blob BLOB;
BEGIN
SELECT PICTURE into dest_blob FROM CHARACTERS WHERE ID = 82;
DBMS_LOB.OPEN(src_bfile, DBMS_LOB.LOB_READONLY);
DBMS_LOB.CREATETEMPORARY( dest_blob, TRUE);
DBMS_LOB.LoadFromFile( DEST_LOB => dest_blob,
SRC_LOB => src_bfile,
AMOUNT => DBMS_LOB.GETLENGTH(src_bfile) );
DBMS_LOB.CLOSE(src_bfile);
COMMIT;
END;
/
sqlplus 命令行调用 (上述脚本)
SQL> @/path/to/script.sql
控制台输出
Directory created.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
SQL Blob 数据检查
SELECT ID FROM Characters
WHERE DBMS_LOB.GETLENGTH(Picture) = 0 OR
DBMS_LOB.GETLENGTH(Picture) IS NULL;
输出
ID
----------
15
44
82
101
环境
- Ubuntu 16.04 LTS,64 位
- Intel Celeron,4 处理器,64-GB HD,2-GB RAM
-
Oracle 11g 速成版:
SQL > select * from v$version Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production PL/SQL Release 11.2.0.2.0 - Production CORE 11.2.0.2.0 Production TNS for Linux: Version 11.2.0.2.0 - Production NLSRTL Version 11.2.0.2.0 - Production
【问题讨论】:
-
尝试
INSERT INTO Characters ( ID, Picture ) VALUES ( 44, EMPTY_BLOB() );,然后使用您的匿名 PL/SQL 块。 SQLFIDDLE -
@MTO 我很欣赏这个建议。但是,我不想追加新行而是更新现有行。您的示例适用于空表。我们可以为
UPDATE设置它吗?或者也许我必须用EMPTY_BLOB实体和writeappend更新图片? -
当您将
DBMS_LOB.GETLENGTH (src_bfile)放入variable并传递变量时会得到什么。可以试一次吗? -
@XING - 我试过没有用:
dest_length:= DBMS_LOB.GETLENGTH (src_bfile) ... AMOUNT => dest_length. -
你所做的是绝对正确的。您需要查看其他地方是否存在问题。