0

我有一些 SQL 代码来填充数据库,效果很好:

INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID) VALUES (1, 1, 1);
INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID) VALUES (2, 1, 1);
INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID) VALUES (3, 1, 2);

EXECUTE RESET_SEQUENCE('DOCUMENT_ELEMENT_ID_SEQ', 4);

为了提高可维护性,我试图用变量替换一些幻数。我以前从未使用过变量,但我读过我需要使用 PL/SQL 块,所以:

DECLARE
    ELEMENT_TEXT SMALLINT := 1;
    ELEMENT_IMAGE SMALLINT := 2;
BEGIN

INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID) VALUES (1, 1, ELEMENT_TEXT);
INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID) VALUES (2, 1, ELEMENT_TEXT);
INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID) VALUES (3, 1, ELEMENT_IMAGE);

EXECUTE RESET_SEQUENCE('DOCUMENT_ELEMENT_ID_SEQ', 4);

END;
/

这工作得很好,除了过程调用:

EXECUTE RESET_SEQUENCE('DOCUMENT_ELEMENT_ID_SEQ', 4);
           *
ERROR en lÝnea 45:
ORA-06550: lÝnea 45, columna 9:
PLS-00103: Se ha encontrado el sÝmbolo "RESET_SEQUENCE" cuando se esperaba uno
de los siguientes:
:= . ( @ % ; immediate
El sÝmbolo ":=" ha sido sustituido por "RESET_SEQUENCE" para continuar.

PLS-00103 错误转换为:

PLS-00103:找到“字符串”但预期以下之一:“字符串”

如果我将呼叫更改为:

EXECUTE IMMEDIATE RESET_SEQUENCE('DOCUMENTO_ELEMENTO_ID_SEQ', 4);

...我明白了:

PLS-00222: en este ßmbito no existe ninguna funci¾n cuyo nombre sea
'RESET_SEQUENCE'
ORA-06550: lÝnea 45, columna 1:
PL/SQL: Statement ignored

...翻译为:

PLS-00222:此范围内不存在名称为“字符串”的函数

我的问题是:

  1. 我是否正确使用了变量,或者对于我的初始目标有更好的解决方案?
  2. 我需要在我的过程调用语法中修复什么,为什么?
4

3 回答 3

1
  1. IMO,如果您有一个带有 3 个参数的程序会更好,其中您将有 1 个插入...然后使用该程序进行插入。这样你就可以添加异常处理,如果发生了什么你就会知道。

  2. 在使用代码的块版本时尝试删除 EXECUTE。我认为你不需要它:)

于 2013-03-08T09:50:40.823 回答
1

过程调用不是普通的 SQL,而是 PL/SQL。因此,您需要从 PL/SQL 上下文中运行它。选项包括:

  • 创建一个 PL/SQL 块并直接调用该过程:

    BEGIN
        RESET_SEQUENCE('DOCUMENT_ELEMENT_ID_SEQ', 4);
    END;
    /
    
  • 如果您在 SQL*Plus,您可以使用EXECUTE 内部命令

    EXECUTE RESET_SEQUENCE('DOCUMENT_ELEMENT_ID_SEQ', 4);
    

我的问题是我在 PL/SQL 块内发出 SQL*Plus 命令。

(截至EXECUTE IMMEDIATE,它是运行动态生成的 SQL 语句或匿名 PL/SQL 块的PL/SQL 命令。它需要一个字符串,与此问题无关。Oracle 仅建议它,因为它的名称类似于 SQL*Plus 命令.)

于 2013-03-08T13:51:45.347 回答
0

如果最初的目标是避免使用幻数,那么解决方案是使用具有这些数字含义的表格并引用它。

所以 ...

 create table element (
   element_id   integer primary key,
   element_name varchar2(30) not null unique);

 insert into element values (1,'Text');
 insert into element values (2,'Image');

 INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID)
 Select 1, 1, element_id
 from   elements
 where  element_name = 'Text';

 INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID)
 Select 1, 1, element_id
 from   elements
 where  element_name = 'Text';

 INSERT INTO PDF_DOCUMENT_ELEMENT (DOCUMENT_ELEMENT_ID, DOCUMENT_ID, ELEMENT_ID)
 Select 1, 1, element_id
 from   elements
 where  element_name = 'Image';
于 2013-03-08T10:43:38.483 回答