【问题标题】:How can I copy a BLOB from a parameter to a local variable in Oracle PL/SQL?如何将 BLOB 从参数复制到 Oracle PL/SQL 中的局部变量?
【发布时间】:2012-04-02 07:21:36
【问题描述】:

我有一个以 BLOB 作为参数的 Oracle PL/SQL 例程。 BLOB 包含一个 .jpg 文件。我想将 BLOB 参数分配给局部变量。然后我想在 BLOB 变量的表中插入(或更新)一个 BLOB 列。

我尝试过这样的事情:

declare
  vATTACHMENT blob;
begin
  dbms_lob.createtemporary(vATTACHMENT, false, dbms_lob.session);
  dbms_lob.write(vATTACHMENT, dbms_lob.lobmaxsize, 1, :pATTACHMENT)); 

  -- do some stuff

  insert into attachments (attachment, file_name)
                   values (vATTACHMENT, vFILE_NAME);
end;

但我收到以下错误:

ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.DBMS_LOB", line 811
ORA-06512: at line 21

我也尝试过像vATTACHMENT := :pATTACHMENT; 这样的直接分配,但它也不想工作。

【问题讨论】:

  • 您尝试直接分配时遇到的具体问题是什么?
  • 更多的是执行 PL/SQL 的组件的问题。它认为前面有冒号的任何东西都是参数,所以它创建了一个参数名称'='。

标签: oracle plsql oracle10g blob


【解决方案1】:

我认为您可以在变量声明中使用DEFAULT 为其赋值,而无需使用赋值运算符:=,例如:

declare
  vATTACHMENT blob DEFAULT :pATTACHMENT;
begin
  -- rest of your code...

【讨论】:

  • 我选择了这个答案,因为它是最简单的,并且完全符合我的需要:允许我在整个 SQL 中使用 vATTACHMENT,只引用一个 :pATTACHMENT。
【解决方案2】:

我只能在pAttachment 为空或为空时得到确切的错误(在 10.2.0.5 中测试)。如果不是,我会得到ORA-21560,因为它不喜欢lobmaxsize。如果我这样做,就可以了:

dbms_lob.write(vATTACHMENT, dbms_lob.getlength(:pATTACHMENT), 1, :pATTACHMENT));

但是从您的 cmets 来看,您在多次引用绑定变量时遇到了一些问题,出于某种原因,我不太明白您不能在 PL/SQL 中进行赋值,因为 := 被误解了 - 这使得使用 PL /SQL 有点不切实际,我想。我有点不清楚您是否直接从您的客户那里将其作为匿名块运行;如果是这样,也许您应该考虑将其作为存储过程来避免这两个问题?然后你可以这样做:

vATTACHMENT := :pATTACHMENT;

...虽然它是传递给过程的参数而不是绑定变量,并且您不需要首先使用副本(正如 Dave Costa 所建议的那样)。

如果您坚持这样运行它,您可能会导致上下文切换并执行以下操作:

select :pATTACHMENT into vATTACHMENT from dual;

但这并不理想;如果你只是想复制,为什么不使用copy procedures

dbms_lob.copy(vATTACHMENT, :pATTACHMENT, dbms_lob.getlength(:pATTACHMENT));

... 这样仍然会打破您的重新引用绑定变量限制,但这个确实理解lobmaxsize

dbms_lob.copy(vATTACHMENT, :pATTACHMENT, dbms_lob.lobmaxsize);

如果 :pATTACHMENT 为空或 null,您仍然会收到错误(我认为是 ORA-22994),因此您需要在调用块之前确保它不存在,或者检查内部。

【讨论】:

  • 谢谢亚历克斯。我的许多问题都源于我的环境。我在 Delphi 7 中使用 TADOCommand。我试图制作 PL/SQL 以适应该组件的某些特性。另外,我确实尝试了 dbms_lob.copy(在我看到你的答案之前),但我一定是参数错误,因为我也无法让它工作。 +1 以获取您答案中的详细信息。
【解决方案3】:

DBMS_LOB.WRITE 的第四个参数应该是RAWVARCHAR2。如果我理解正确,您将现有的 BLOB 绑定到 :pATTACHMENT 占位符,因此您传递的类型不正确。

为什么需要将它分配给临时 BLOB?在我看来,这应该可行:

insert into attachments (attachment, file_name)
               values (:pATTACHMENT, vFILE_NAME);

例如,这运行良好:

DECLARE
  PROCEDURE insert_blob( p_blob BLOB) IS
  BEGIN
    INSERT INTO t_dave (b) VALUES (p_blob);
  END;
BEGIN
  insert_blob( empty_blob() );
END;
/

【讨论】:

  • 直接插入确实有效,但由于我正在使用的组件,我不能在 PL/SQL 中多次引用 :pATTACHMENT 参数,所以我想复制它的值到一个局部变量。然后我可以根据需要经常引用它。
猜你喜欢
  • 1970-01-01
  • 2012-10-14
  • 2014-07-12
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 2013-01-09
  • 1970-01-01
相关资源
最近更新 更多