PL/SQLでT-SQLのように変数を宣言して使用するには?

SQL Serverでは、ストアドプロシージャの本体をテストする際に、本体をSSMSにコピーし、ページ上部の変数をDECLAREし、サンプル値を設定して、そのまま実行することがよくあります。

例えば、私のプロシージャが

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

とすると、テスト用のSQLは次のようになります。

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

    SELECT @Name

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

これは私が思いついた最も近いものですが、私は "PLS-00428: an INTO clause is expected in this SELECT statement&quot が表示されます。

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'を要求しています。実際には、レコードを画面に表示したいだけで、別のテーブルに保存したいわけではありません。....

RESOLVED:

Allanさんのおかげで、十分に動作するようになりました。 Oracle SQL Developerは、与えられたパラメータ値を記憶しているようです。 しかし、PL/SQL Developerは、これとは何の関係もありません。....

.

もし、"Run As Script" とすれば、デフォルトに従いますが、結果はグリッドやスプレッドシートではなく、ASCIテキストとしてのみ返されます。

.

ソリューション

改訂版の回答

他のプログラムからこのコードを呼び出さないのであれば、PL/SQLをスキップして、バインド変数を使用してSQLで厳密に処理するという方法もあります。

var myname varchar2(20);

exec :myname := 'Tom';

SELECT *
FROM   Customers
WHERE  Name = :myname;

多くのツール(Toad や SQL Developer など)では、varexec の記述を省略すると、プログラムが値の入力を促すようになります。


オリジナルの回答

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

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

     dbms_output.print_line(myname);
END;

しかし、結果セットを返そうとしている場合、これはあまり役に立ちません。その場合には、コレクションを返すか、リフカーソルを返すことになります。しかし、これらの解決策を使うには、コードを関数やプロシージャで囲み、結果を消費できるものからその関数やプロシージャを実行する必要があります。この方法で動作する関数は、次のようなものになります。

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;
解説 (6)

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;
解説 (0)