3

私はオラクルが初めてです。以下を使用してストアド プロシージャを作成する場合:

CREATE OR REPLACE PROCEDURE PROCEDURE1 
AS
BEGIN

  SELECT FIRSTNAME,
         LASTNAME
    INTO FirstName,LastName
    FROM EMPLOYEE;

END PROCEDURE1;

次のエラーが表示されます。

PL/SQL 文は無視されます 識別子 FIRSTNAME を宣言する必要があります ORA-00904 識別子が無効です

4

4 に答える 4

7

変数を設定する前に、変数を宣言する必要があります。

CREATE OR REPLACE PROCEDURE PROCEDURE1 
AS

 FirstName EMPLOYEE.FIRSTNAME%TYPE;
 LastName EMPLOYEE.LASTNAME%TYPE;

BEGIN

  SELECT FIRSTNAME,
         LASTNAME
    INTO FirstName,LastName
    FROM EMPLOYEE;

END PROCEDURE1;

%TYPE 表記は、列のデータ型に一致するデータ型宣言の省略形です。そのデータ型が変更された場合でも、プロシージャを更新する必要はありません。

于 2010-12-02T17:33:09.627 に答える
3

変数を宣言する必要があります。

CREATE OR REPLACE
PROCEDURE PROCEDURE1 AS
 V_FIRSTNAME VARCHAR2(60);
 V_LASTNAME  VARCHAR2(60);
BEGIN
        SELECT FIRSTNAME,LASTNAME
         INTO V_FIRSTNAME ,V_LASTNAME  
         FROM EMPLOYEE;
END PROCEDURE1;

コメントへの返信として、PL/SQL ブロック内の SQL ステートメントは 1 つのレコードしか取得できません。複数のレコードをフェッチする必要がある場合は、レコードをカーソルに格納して処理する必要があります。

CREATE OR REPLACE
    PROCEDURE PROCEDURE1 AS

     CURSOR EMP_CUR IS
         SELECT FIRSTNAME,LASTNAME
         FROM EMPLOYEE;
    EMP_CUR_REC EMP_CUR%ROWTYPE;

    BEGIN
     FOR EMP_CUR_REC IN EMP_CUR LOOP
         -- do your processing
         DBMS_OUTPUT.PUT_LINE('Employee first name is ' || EMP_CUR_REC.FIRSTNAME);
         DBMS_OUTPUT.PUT_LINE('Employee last name is ' || EMP_CUR_REC.LASTNAME);
    END LOOP;
    END PROCEDURE1;

説明する: EMP_CUR実行する SQL ステートメントを保持します。 EMP_CUR_RECSQL ステートメントによってフェッチされるレコードを保持します。 %ROWTYPERecord が、データを保持する行と同じデータ型になることを示します

FOR LOOP各レコードをフェッチし、実行する必要がある処理を実行できます。

于 2010-12-02T17:31:50.170 に答える
2


「AS」キーワードは機能しないと思います。うまくいかない場合は、「IS」を使用してください。
残りは問題なく、非常に良いヒントです。

PL/SQL に関するヘルプが必要な場合は、このリンクを参照してください。とてもシンプルで理解しやすいです。
http://plsql-tutorial.com/

これは、あなたが得ているエラーに対する私の解決策です。

CREATE OR REPLACE PROCEDURE PROCEDURE1 IS
  v_FIRSTNAME EMPLOYEE.FIRSTNAME%TYPE;
  v_LASTNAME EMPLOYEE.LASTNAME%TYPE;
  CURSOR EMPCURSOR IS
  SELECT FIRSTNAME, LASTNAME FROM EMPLOYEE;      
  BEGIN   
     IF NOT EMPCURSOR%ISOPEN THEN
         OPEN EMPCURSOR;
     END IF;
     LOOP
        FETCH EMPCURSOR INTO V_FIRSTNAME,V_LASTNAME;
        EXIT WHEN EMPCURSOR%NOTFOUND;
     END LOOP;
     IF EMPCURSOR%ISOPEN THEN
        CLOSE EMPCURSOR;
     END;
  END PROCEDURE1;

DBMS_OUTPUT.PUT_LINE(V_FIRSTNAME || ','|| V_LASTNAME)ループ内で , を使用して出力を表示することもできます。ただし、それを行うには、最初にコマンドを実行する必要がありますserver output on

于 2010-12-02T17:45:09.557 に答える
1

上記の@Sathyaの回答に対する回答で、@ kayakは、「SQLサーバーの場合のように、テーブル名から*を選択するか、テーブル名から名、姓を選択することができますか」と尋ねました。

はい、できますが、WHERE句を含めるか、カーソルを使用する必要があります。結果を単一の行に制限するWHERE句を含めると、次のように記述できます。

CREATE OR REPLACE PROCEDURE PROCEDURE1
IS
  rowEmployees EMPLOYEE%ROWTYPE;
BEGIN
  SELECT *
    INTO rowEmployees
    FROM EMPLOYEE
    WHERE EMPLOYEE_ID = 12345;
END PROCEDURE1; 

一方、テーブル内のすべての行を処理するためにWHERE句がない場合、または結果を1行に制限しないWHERE句がある場合は、カーソルを使用できます。次の方法:

CREATE OR REPLACE PROCEDURE PROCEDURE1 IS
BEGIN
  FOR rowEmployees IN (SELECT *
                         FROM EMPLOYEE
                         WHERE EMPLOYEE_ID IN (12345, 67890, 111213, 141516))
  LOOP
    <do something with rowEmployees here>
  END LOOP;
END PROCEDURE1; 

共有してお楽しみください。

于 2010-12-03T12:17:22.457 に答える