web-dev-qa-db-ja.com

T-SQLで行うように、PL / SQLで変数を宣言して使用するにはどうすればよいですか?

Sql Serverでは、多くの場合、ストアドプロシージャの本体をテストするときに、本体をSSMSにコピーし、ページ上部の変数を宣言し、それらをいくつかのサンプル値に設定し、本体をそのまま実行します。

たとえば、私のprocが

CREATE PROC MySampleProc
    @Name   VARCHAR(20)
AS
    SELECT @Name

その後、私のテストSQLは

DECLARE @Name VARCHAR(20)
SET     @Name = 'Tom'

    SELECT @Name

これに相当するOracle PL/SQLとは何ですか?

これは私が思いついた最も近いものですが、「PLS-00428:このSELECTステートメントにはINTO句が必要です」というメッセージが表示されます。

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     select myname from DUAL;
END;

これは私が本当にやろうとしていることの良い例です:

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     SELECT *
     FROM   Customers
     WHERE  Name = myname;
END;

しかし、ここでも、レコードを別のテーブルに保存するのではなく、画面に印刷するだけの場合に「INTO」が必要です。

解決済み:

@Allanのおかげで、十分に機能しています。 Oracle SQL Developerは、提供されたパラメータ値を記憶しているようです。しかし、PL/SQL Developerはこれとは何の関係もありません。

enter image description here

「スクリプトとして実行」すると、デフォルトに従いますが、結果はグリッド/スプレッドシートではなくASCIテキストとしてのみ返されます

enter image description here

24
Tom Halladay

修正された回答

別のプログラムからこのコードを呼び出さない場合、オプションはPL/SQLをスキップし、バインド変数を使用してSQLで厳密に実行します。

var myname varchar2(20);

exec :myname := 'Tom';

SELECT *
FROM   Customers
WHERE  Name = :myname;

多くのツール(ToadやSQL Developerなど)では、varおよびexecステートメントを省略すると、プログラムは値の入力を求めます。


元の回答

T-SQLとPL/SQLの大きな違いは、Oracleではクエリの結果を暗黙的に返すことができないことです。結果は常に何らかの方法で明示的に返される必要があります。最も簡単な方法は、DBMS_OUTPUTprintとほぼ同等)変数を出力します。

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     dbms_output.print_line(myname);
END;

ただし、結果セットを返そうとしている場合、これはそれほど役に立ちません。その場合、コレクションまたはrefcursorを返す必要があります。ただし、これらのソリューションのいずれかを使用するには、関数またはプロシージャでコードをラップし、結果を消費できるものから関数/プロシージャを実行する必要があります。この方法で機能する関数は次のようになります。

CREATE FUNCTION my_function (myname in varchar2)
     my_refcursor out sys_refcursor
BEGIN
     open my_refcursor for
     SELECT *
     FROM   Customers
     WHERE  Name = myname;

     return my_refcursor;
END my_function;
20
Allan

Oracle PL/SQLでは、複数の行を返す可能性のあるクエリを実行している場合、結果を反復処理するカーソルが必要です。最も簡単な方法は、forループを使用することです。例:

declare
  myname varchar2(20) := 'tom';
begin
  for result_cursor in (select * from mytable where first_name = myname) loop
    dbms_output.put_line(result_cursor.first_name);
    dbms_output.put_line(result_cursor.other_field);
  end loop;
end;

1行のみを返すクエリがある場合は、select...into...構文を使用できます。例:

declare 
  myname varchar2(20);
begin
  select first_name into myname 
    from mytable 
    where person_id = 123;
end;
4
GriffeyDog

変数は定義されていませんが、宣言されています。

これは pl/sqlブロックで変数を宣言する の重複の可能性があります

しかし、あなたはここを見ることができます:

http://docs.Oracle.com/cd/B19306_01/appdev.102/b14261/fundamentals.htm#i27306

http://docs.Oracle.com/cd/B19306_01/appdev.102/b14261/overview.htm

更新:

ここを参照してください: 動的SQLを実行するOracle PL/SQL匿名ブロックから結果セット/カーソルを返す方法?

1
rkosegi