web-dev-qa-db-ja.com

変数を宣言して同じOracle SQLスクリプトで使用する方法

再利用可能なコードを書き、最初にいくつかの変数を宣言し、スクリプトでそれらを再利用する必要があります。

DEFINE stupidvar = 'stupidvarcontent';

SELECT stupiddata
FROM stupidtable
WHERE stupidcolumn = &stupidvar;

SQLDeveloperの使用など、変数を宣言してそれに続く文で再利用するにはどうすればよいですか。


試行回数

  • DECLAREセクションを使用して、以下のSELECTステートメントをBEGINおよびEND;に挿入します。 &stupidvarを使用して変数にアクセスします。
  • キーワードDEFINEを使用して変数にアクセスします。
  • キーワードVARIABLEを使用して変数にアクセスします。

しかし私は私の試みの間にあらゆる種類のエラーを得ています(未束縛変数、構文エラー、期待されるSELECT INTO...)。

110
bl4ckb0l7

SQL * Plusスクリプトで変数を宣言する方法はいくつかあります。

1つ目はVARを使うことです。 VARに値を割り当てるためのメカニズムは、EXEC呼び出しを使用することです。

SQL> var name varchar2(20)
SQL> exec :name := 'SALES'

PL/SQL procedure successfully completed.

SQL> select * from dept
  2  where dname = :name
  3  /

    DEPTNO DNAME          LOC
---------- -------------- -------------
        30 SALES          CHICAGO

SQL>

VARは、OUTパラメータまたは関数を持つストアドプロシージャを呼び出したいときに特に便利です。

代替的に、置換変数を使用することができます。これらは対話モードに適しています。

SQL> accept p_dno Prompt "Please enter Department number: " default 10
Please enter Department number: 20
SQL> select ename, sal
  2  from emp
  3  where deptno = &p_dno
  4  /
old   3: where deptno = &p_dno
new   3: where deptno = 20

ENAME             SAL
---------- ----------
CLARKE            800
ROBERTSON        2975
RIGBY            3000
KULASH           1100
GASPAROTTO       3000

SQL>

他のスクリプトを呼び出すスクリプトを作成しているときは、変数を事前に定義すると便利です。

SQL> def p_dno = 40
SQL> select ename, sal
  2  from emp
  3  where deptno = &p_dno
  4  /
old   3: where deptno = &p_dno
new   3: where deptno = 40

no rows selected

SQL>

最後に無名PL/SQLブロックがあります。ご覧のとおり、対話的に宣言された変数に値を代入することができます。

SQL> set serveroutput on size unlimited
SQL> declare
  2      n pls_integer;
  3      l_sal number := 3500;
  4      l_dno number := &dno;
  5  begin
  6      select count(*)
  7      into n
  8      from emp
  9      where sal > l_sal
 10      and deptno = l_dno;
 11      dbms_output.put_line('top earners = '||to_char(n));
 12  end;
 13  /
Enter value for dno: 10
old   4:     l_dno number := &dno;
new   4:     l_dno number := 10;
top earners = 1

PL/SQL procedure successfully completed.

SQL>
123
APC

Char変数の場合は二重引用符を使ってみてください。

DEFINE stupidvar = "'stupidvarcontent'";

または

DEFINE stupidvar = 'stupidvarcontent';

SELECT stupiddata  
FROM stupidtable  
WHERE stupidcolumn = '&stupidvar'

更新日:

SQL*Plus: Release 10.2.0.1.0 - Production on Wed Aug 25 17:13:26 2010

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

SQL> conn od/od@etalon
Connected.
SQL> define var = "'FL-208'";
SQL> select code from product where code = &var;
old   1: select code from product where code = &var
new   1: select code from product where code = 'FL-208'

CODE
---------------
FL-208

SQL> define var = 'FL-208';
SQL> select code from product where code = &var;
old   1: select code from product where code = &var
new   1: select code from product where code = FL-208
select code from product where code = FL-208
                                      *
ERROR at line 1:
ORA-06553: PLS-221: 'FL' is not a procedure or is undefined
23
be here now

PL/SQL v.10では

キーワードdeclareは変数を宣言するために使用されます

DECLARE stupidvar varchar(20);

宣言するときに設定できる値を割り当てる

DECLARE stupidvar varchar(20) := '12345678';

またはその変数に何かを選択するにはINTOステートメントを使用しますが、ステートメントをBEGINENDでラップする必要があります。また、必ず単一の値のみが返されるようにし、セミコロンを忘れないでください。

そのため、完全な声明は次のようになります。

DECLARE stupidvar varchar(20);
BEGIN
    SELECT stupid into stupidvar FROM stupiddata CC 
    WHERE stupidid = 2;
END;

あなたの変数はBEGINENDの中だけで使えるので、もしあなたが複数を使いたいのなら、あなたは複数のBEGIN ENDラッピングをしなければならないでしょう。

DECLARE stupidvar varchar(20);
BEGIN
    SELECT stupid into stupidvar FROM stupiddata CC 
    WHERE stupidid = 2;

    DECLARE evenmorestupidvar varchar(20);
    BEGIN
        SELECT evenmorestupid into evenmorestupidvar FROM evenmorestupiddata CCC 
        WHERE evenmorestupidid = 42;

        INSERT INTO newstupiddata (newstupidcolumn, newevenmorestupidstupidcolumn)
        SELECT stupidvar, evenmorestupidvar 
        FROM dual

    END;
END;

これが時間を節約することを願っています

14

日付を宣言してからSQL Developerで使用する場合。

DEFINE PROPp_START_DT = TO_DATE('01-SEP-1999')

SELECT * 
FROM proposal 
WHERE prop_start_dt = &PROPp_START_DT
5
SVK

問題は、スクリプト内で変数を使用しようとしているということですが、それはSQL * Plusで使用されることを意味します。

問題は、あなたが引用符を逃したそしてOracleが数値に値を解析できないことです。

SQL> DEFINE num = 2018
SQL> SELECT &num AS your_num FROM dual;
old   1: SELECT &num AS your_num FROM dual
new   1: SELECT 2018 AS your_num FROM dual

  YOUR_NUM
----------
      2018

Elapsed: 00:00:00.01

このサンプルは自動型変換(またはそれが呼ばれるものは何でも)のためにうまく働きます。

SQL * PlusでDEFINEと入力して確認すると、num変数がCHARであることがわかります。

SQL>define
DEFINE NUM             = "2018" (CHAR)

この場合は問題になりません。有効な数値であれば、Oracleは文字列を数値に解析することができるためです。

文字列がnumberに解析できない場合、Oracleはそれを処理できません。

SQL> DEFINE num = 'Doh'
SQL> SELECT &num AS your_num FROM dual;
old   1: SELECT &num AS your_num FROM dual
new   1: SELECT Doh AS your_num FROM dual
SELECT Doh AS your_num FROM dual
       *
ERROR at line 1:
ORA-00904: "DOH": invalid identifier

引用符で囲むと、Oracleに数値の解析を強制しないでください。

17:31:00 SQL> SELECT '&num' AS your_num FROM dual;
old   1: SELECT '&num' AS your_num FROM dual
new   1: SELECT 'Doh' AS your_num FROM dual

YOU
---
Doh

したがって、元の質問に答えるには、このサンプルのようにする必要があります。

SQL> DEFINE stupidvar = 'X'
SQL>
SQL> SELECT 'print stupidvar:' || '&stupidvar'
  2  FROM dual
  3  WHERE dummy = '&stupidvar';
old   1: SELECT 'print stupidvar:' || '&stupidvar'
new   1: SELECT 'print stupidvar:' || 'X'
old   3: WHERE dummy = '&stupidvar'
new   3: WHERE dummy = 'X'

'PRINTSTUPIDVAR:'
-----------------
print stupidvar:X

Elapsed: 00:00:00.00

問合せ列値を使用して、SQL * Plusに変数を格納する方法は他にもあります。

COL[UMN]には、値を格納するためのnew_valueオプションがあります。フィールド名で問い合わせます。

SQL> COLUMN stupid_column_name new_value stupid_var noprint
SQL> SELECT dummy || '.log' AS stupid_column_name
  2  FROM dual;

Elapsed: 00:00:00.00
SQL> SPOOL &stupid_var.
SQL> SELECT '&stupid_var' FROM DUAL;
old   1: SELECT '&stupid_var' FROM DUAL
new   1: SELECT 'X.log' FROM DUAL

X.LOG
-----
X.log

Elapsed: 00:00:00.00
SQL>SPOOL OFF;

ご覧のとおり、X.logの値はstupid_var変数に設定されているので、現在のディレクトリにX.logファイルにログがあることがわかります。その中に。

3
Laszlo Lugosi

Matas '答えを追加したいだけです。多分それは明白かもしれませんが、変数はBEGIN-END構造の中でのみアクセス可能であることを理解するために長い間探しました。後でそれをいくつかのコードで使用する必要がある、あなたはこのコードをBEGIN-ENDブロックの中に入れる必要があります

これらのブロックはネストすることができます

DECLARE x NUMBER;
  BEGIN
    SELECT PK INTO x FROM table1 WHERE col1 = 'test';

    DECLARE y NUMBER;
    BEGIN
    SELECT PK INTO y FROM table2 WHERE col2 = x;

    INSERT INTO table2 (col1, col2)
      SELECT y,'text'
      FROM dual
      WHERE exists(SELECT * FROM table2);
    COMMIT;
  END;
END;
3
Katia Savina

これがあなたの答えです:

DEFINE num := 1;       -- The semi-colon is needed for default values.
SELECT &num FROM dual;
2

Toadではこれを使用します:

declare 
    num number;
begin 
    ---- use 'select into' works 
    --select 123 into num from dual;

    ---- also can use :=
    num := 123;
    dbms_output.Put_line(num);
end;

その後、値はDBMS Output Windowに出力されます。

here および here2 への参照。

0
yu yang Jian