변수를 선언하고 동일한 Oracle SQL 스크립트에서 사용하는 방법은 무엇입니까?


133

재사용 가능한 코드를 작성하고 처음에 일부 변수를 선언하고 스크립트에서 다음과 같이 재사용해야합니다.

DEFINE stupidvar = 'stupidvarcontent';

SELECT stupiddata
FROM stupidtable
WHERE stupidcolumn = &stupidvar;

변수를 선언하고 SQLDeveloper를 사용하는 것과 같은 다음 명령문에서 어떻게 재사용 할 수 있습니까?


시도

  • 선언 섹션을 사용하여에 다음 SELECT 문을 삽입 BEGIN하고 END;. 을 사용하여 변수에 액세스합니다 &stupidvar.
  • 키워드 DEFINE를 사용하여 변수에 액세스하십시오.
  • 키워드를 사용하여 VARIABLE변수에 액세스하십시오.

그러나 시도하는 동안 모든 종류의 오류가 발생합니다 (바인딩되지 않은 변수, 구문 오류, 예상 SELECT INTO...).


2
@APC가 허용하는 답변의 접근 방식은 PL / SQL없이 사용할 수 있습니다 (예 : 질문에 따라 SQL 개발자 워크 시트). 변수를 한 줄 (세미콜론 없음)로 선언 한 다음 exec 줄을 사용하여 값을 설정하고 (세미콜론으로 끝남) select 문을 선택하십시오. 마지막으로, 명령문 (F9)이 아닌 스크립트 (F5)로 실행하십시오.
Amos M. Carpenter

답변:


139

SQL * Plus 스크립트에서 변수를 선언하는 방법에는 여러 가지가 있습니다.

첫 번째는 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>

6
"바인드 변수"라는 용어를 제외하고는 모두 좋습니다. VAR 선언은 바인드 변수를 작성하고 ACCEPT 또는 DEFINE은 대체 변수를 작성합니다.
Dave Costa

1
변수 + 문자열을 연결할 수 있습니까?
Ecropolis

@Ecropolis-예. 기본적으로 SQL Plus 사용 기간입니다. SET CONCAT을 사용하여 변수 이름 바로 뒤에 오는 영숫자 문자에서 대체 변수 이름을 구분하는 문자를 정의하십시오. PL / SQL 또는 SQL에서 이중 파이프를 사용하십시오 || 연결합니다.
Laszlo Lugosi

SQL이 표준 언어 인 경우 모든 곳에서 작동하는 표준 참조를 찾는 것이 왜 그렇게 어려운가? WTF ???
jww

1
@jww-SQL은 표준이지만 항상 정확한 구문을 지정하지 않으므로 다른 RDBMS 제품이 다르게 구현할 수 있습니다. 날짜 산술이 좋은 예입니다. 또한 Oracle과 같은 오래된 데이터베이스 제품은 표준에 앞서 기능을 도입하기도했습니다 (예 : 계층 적 CONNECT BY 구문). 그러나이 경우 클라이언트 도구 인 SQL * Plus에 대해 논의하고 있으므로 ANSI 표준에서는 다루지 않습니다.
APC

28

char 변수 인 경우 큰 따옴표를 사용해보십시오.

DEFINE stupidvar = "'stupidvarcontent'";

또는

DEFINE stupidvar = 'stupidvarcontent';

SELECT stupiddata  
FROM stupidtable  
WHERE stupidcolumn = '&stupidvar'

upd :

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

귀하의 답변에 감사드립니다.하지만 var을 큰 따옴표로 묶으면을 얻습니다 ORA-01008: not all variables bound.
bl4ckb0l7

1
확실한! DEFINE num = 1; SELECT &num FROM dual;리드 : ORA-01008: not all variables bound
bl4ckb0l7

@ bl4ckb0l7-SQL * Plus 에서이 작업을 시도하지 않는 것이 좋습니다.
Laszlo Lugosi

20

PL / SQL v.10에서

키워드 선언은 변수를 선언하는 데 사용됩니다

DECLARE stupidvar varchar(20);

선언 할 때 설정할 수있는 값을 지정하려면

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

또는 당신이 사용하는 변수로 어떤 선택 INTO문을, 그러나 당신은에 문을 포장해야 BEGIN하고 END또한 당신은 단지 하나의 값이 반환되어 있는지 확인하고, 세미콜론을 잊지 마세요 필요합니다.

따라서 전체 내용은 다음과 같습니다.

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;

희망이 시간을 절약


7

날짜를 선언하고 SQL Developer에서 사용하려는 경우.

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

SELECT * 
FROM proposal 
WHERE prop_start_dt = &PROPp_START_DT

5

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;

5

질문은 스크립트에서 변수를 사용하려고한다는 것입니다 .SQL * Plus에서 사용됩니다.

문제는 당신이 따옴표를 놓 쳤고 오라클은 값을 숫자로 파싱 할 수 없다는 것입니다.

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은 유효한 숫자이면 문자열을 숫자로 구문 분석 할 수 있으므로이 경우에는 문제가되지 않습니다.

문자열이 숫자로 구문 분석 될 수없는 경우, 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

Query Column Value 를 사용하여 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 파일에 로그가 있습니다.


2

답은 다음과 같습니다.

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

1
저도 마찬가지입니다. ODT를 사용하여 다음을 실행합니다. DEFINE num : = 1; 듀얼에서 숫자 선택; 그리고 내가 얻는 것은 : ORA-00904 : "NUM": 잘못된 식별자 00904. 00000- "% s : invalid identifier"* 원인 : * 작업 : 줄 오류 : 2 열 : 8
toha

0

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 OutputWindow 로 인쇄됩니다 .

herehere2 참조 .


0

때때로 사용자에게 값을 입력하도록 요청하지 않고 매크로 변수를 사용해야합니다. 대부분의 경우 선택적 스크립트 매개 변수를 사용하여 수행해야합니다. 다음 코드는 완벽하게 작동합니다

column 1 noprint new_value 1
select '' "1" from dual where 2!=2;
select nvl('&&1', 'VAH') "1" from dual;
column 1 clear
define 1

rdbms / sql 디렉토리에서 비슷한 코드가 발견되었습니다.


0

매개 변수를 한 번만 지정하고 여러 위치에 복제해야하는 경우 가능한 방법 중 하나는 다음과 같습니다.

SELECT
  str_size  /* my variable usage */
  , LPAD(TRUNC(DBMS_RANDOM.VALUE * POWER(10, str_size)), str_size, '0') rand
FROM
  dual  /* or any other table, or mixed of joined tables */
  CROSS JOIN (SELECT 8 str_size FROM dual);  /* my variable declaration */

이 코드는 8 자리 난수 문자열을 생성합니다.

str_size상수를 유지 하는 일종의 별칭을 만듭니다 8. 쿼리에서 두 번 이상 사용되도록 교차 결합됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.