결과가 null 일 때 PL / SQL에서 변수를 선택하는 방법은 무엇입니까?
쿼리가 아무것도 반환하지 않을 수 있다는 점을 고려하여 변수를 선택하기 위해 쿼리를 한 번만 실행하는 방법이 있습니까? 그런 경우 변수는 null이어야합니다.
현재 select into
쿼리가 아무것도 반환하지 않으면 PL / SQL이 변수가 설정되지 않는다고 불평하기 때문에 직접 변수를 수행 할 수 없습니다 . 쿼리를 두 번만 실행할 수 있습니다. 첫 번째 쿼리는 개수를 계산하고 개수가 0이면 변수를 null로 설정하고 개수가 1이면 변수를 선택합니다.
따라서 코드는 다음과 같습니다.
v_column my_table.column%TYPE;
v_counter number;
select count(column) into v_counter from my_table where ...;
if (v_counter = 0) then
v_column := null;
elsif (v_counter = 1) then
select column into v_column from my_table where ...;
end if;
감사.
업데이트 : 예외를 사용하지 않은 이유는를 할당 한 후에도 여전히 다음과 같은 논리 가 있으며 다음 코드로 다시 이동하려면 예외 섹션에서 v_column
사용해야 goto
합니다. 저는 goto
대사가 좀 망설입니다 .
NO_DATA_FOUND
변수를로 설정하여 예외를 간단히 처리 할 수 있습니다 NULL
. 이렇게하면 쿼리가 하나만 필요합니다.
v_column my_table.column%TYPE;
BEGIN
BEGIN
select column into v_column from my_table where ...;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_column := NULL;
END;
... use v_column here
END;
나는 그것이 오래된 스레드라는 것을 알고 있지만 여전히 대답 할 가치가 있다고 생각합니다.
select (
SELECT COLUMN FROM MY_TABLE WHERE ....
) into v_column
from dual;
사용 예 :
declare v_column VARCHAR2(100);
begin
select (SELECT TABLE_NAME FROM ALL_TABLES WHERE TABLE_NAME = 'DOES NOT EXIST')
into v_column
from dual;
DBMS_OUTPUT.PUT_LINE('v_column=' || v_column);
end;
Cursor FOR LOOP 문을 사용하는 것이 제가 가장 좋아하는 방법입니다.
명시 적 커서를 사용하는 것보다 안전합니다. 닫는 것을 기억할 필요가 없기 때문에 커서를 "누설"할 수 없기 때문입니다.
"into"변수가 필요하지 않고, "FETCH"할 필요도 없으며, "NO DATA FOUND"예외를 포착하고 처리 할 필요가 없습니다.
시도해보십시오. 다시는 가지 않을 것입니다.
v_column my_table.column%TYPE;
v_column := null;
FOR rMyTable IN (SELECT COLUMN FROM MY_TABLE WHERE ....) LOOP
v_column := rMyTable.COLUMN;
EXIT; -- Exit the loop if you only want the first result.
END LOOP;
MAX를 사용하는 것은 어떻습니까? 이렇게하면 데이터가 없으면 변수가 NULL로 설정되고 그렇지 않으면 최대 값이 설정됩니다.
0 또는 1 값을 예상하므로 MAX를 사용해도 좋습니다.
v_column my_table.column%TYPE;
select MAX(column) into v_column from my_table where ...;
위의 모든 답변에서 Björn의 답변 은 가장 우아하고 짧은 것 같습니다. 개인적으로이 방법을 여러 번 사용했습니다. MAX 또는 MIN 함수는 작업을 똑같이 잘 수행합니다. 완전한 PL / SQL은 where 절만 지정해야합니다.
declare v_column my_table.column%TYPE;
begin
select MIN(column) into v_column from my_table where ...;
DBMS_OUTPUT.PUT_LINE('v_column=' || v_column);
end;
커서를 사용하는 것이 좋습니다. 커서 반입은 항상 단일 행이며 (대량 수집을 사용하지 않는 한) 커서는 no_data_found 또는 too_many_rows 예외를 자동으로 발생시키지 않습니다. 한 번 열렸을 때 커서 속성을 검사하여 행이 있는지, 몇 개인 지 확인할 수 있습니다.
declare
v_column my_table.column%type;
l_count pls_integer;
cursor my_cursor is
select count(*) from my_table where ...;
begin
open my_cursor;
fetch my_cursor into l_count;
close my_cursor;
if l_count = 1 then
select whse_code into v_column from my_table where ...;
else
v_column := null;
end if;
end;
또는 더 간단합니다.
declare
v_column my_table.column%type;
cursor my_cursor is
select column from my_table where ...;
begin
open my_cursor;
fetch my_cursor into v_column;
-- Optional IF .. THEN based on FOUND or NOTFOUND
-- Not really needed if v_column is not set
if my_cursor%notfound then
v_column := null;
end if;
close my_cursor;
end;
유연성과 속도를 위해이 구문을 사용합니다.
begin
--
with KLUJ as
( select 0 ROES from dual
union
select count(*) from MY_TABLE where rownum = 1
) select max(ROES) into has_rows from KLUJ;
--
end;
Dual returns 1 row, rownum adds 0 or 1 rows, and max() groups to exactly 1. This gives 0 for no rows in a table and 1 for any other number of rows.
I extend the where clause to count rows by condition, remove rownum to count rows meeting a condition, and increase rownum to count rows meeting the condition up to a limit.
COALESCE
will always return the first non-null result. By doing this, you will get the count that you want or 0:
select coalesce(count(column) ,0) into v_counter from my_table where ...;
'program tip' 카테고리의 다른 글
MySQL의 열 이름 "order"에 대한 대안 (0) | 2020.11.17 |
---|---|
자바에 '조건이 참이 될 때까지 차단'기능이 있습니까? (0) | 2020.11.17 |
EnumSet은 실제로 무엇을 의미합니까? (0) | 2020.11.17 |
JavaScript를 사용하여 한 번에 요소의 여러 속성 설정 (0) | 2020.11.17 |
동일한 값을 가진 행 수 계산 (0) | 2020.11.17 |