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: 'string'が見つかりましたが、次のいずれかが必要です: 'string'

呼び出しを次のように変更すると:

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: この有効範囲には'string'という名前の関数が存在しません

私の質問は次のとおりです。

  1. 変数を正しく使用していますか、それとも最初の目標に対するより良い解決策がありますか?
  2. プロシージャ コールの構文で何を修正する必要がありますか?またその理由は何ですか?
4

3 に答える 3

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 コマンドです。文字列を想定しており、この質問とは何の関係もありません。名前が SQL*Plus コマンドに似ているため、オラクルはそれを提案しただけです。 .)

于 2013-03-08T13:51:45.347 に答える
1
  1. IMO、3つのパラメーターを持つ手順があり、1つの挿入が行われるとよいでしょう...そしてその手順を使用して挿入を行います。そうすれば、例外処理を追加でき、何かが起こった場合に知ることができます。

  2. コードのブロック バージョンを使用する場合は、EXECUTE を削除してみてください。私はあなたがそれを必要とは思わない:)

于 2013-03-08T09:50:40.823 に答える
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 に答える