PL/SQL 블록의 테이블에 행이 있는지 확인하는 올바른 방법
어제 몇 가지 작업을 작성했는데 PL/SQL을 사용할 때 테이블에 행이 있는지 확인하는 올바른 방법 및 승인된 방법을 잘 모르겠다는 생각이 들었습니다.
예를 들어 표를 사용합니다.
PERSON (ID, Name);
분명히 다음과 같은 것은 할 수 없습니다(비밀 방법이 없는 한).
BEGIN
IF EXISTS SELECT id FROM person WHERE ID = 10;
-- do things when exists
ELSE
-- do things when doesn't exist
END IF;
END;
그래서 이 문제를 해결하기 위한 나의 표준 방법은 다음과 같습니다.
DECLARE
tmp NUMBER;
BEGIN
SELECT id INTO tmp FROM person WHERE id = 10;
--do things when record exists
EXCEPTION
WHEN no_data_found THEN
--do things when record doesn't exist
END;
하지만 그것이 받아들여지는 방법인지, 아니면 더 나은 확인 방법이 있는지, 누군가 나와 지혜를 공유해 준다면 정말 고맙겠다.
난 일반 코드를 예외 블록에 넣지 않을 거야.조건을 만족하는 행이 존재하는지 확인하고 다음 순서로 진행하십시오.
declare
any_rows_found number;
begin
select count(*)
into any_rows_found
from my_table
where rownum = 1 and
... other conditions ...
if any_rows_found = 1 then
...
else
...
end if;
테이블에 행이 있는지 확인하기 위해 독립 실행형 SELECT를 사용하는 IMO 코드가 데이터베이스를 제대로 이용하고 있지 않은지 확인합니다.이 예에서는 ID 값이 하드 코딩되어 있지만 "실제"에서는 그렇지 않습니다(적어도 내 환경에서는 다를 수 있습니다).일반적인 앱에서는 커서를 사용하여 데이터를 찾습니다. 예를 들어 청구서 데이터를 보고 고객이 존재하는지 여부를 확인할 필요가 있는 앱이 있다고 가정해 보겠습니다.앱의 본체는 다음과 같습니다.
FOR aRow IN (SELECT * FROM INVOICES WHERE DUE_DATE < TRUNC(SYSDATE)-60)
LOOP
-- do something here
END LOOP;
또,-- do something here
고객이 존재하는지, 존재하지 않는 경우 오류 메시지를 인쇄하는지 확인합니다.
이를 위한 한 가지 방법은 다음과 같이 싱글톤 SELECT를 넣는 것입니다.
-- Check to see if the customer exists in PERSON
BEGIN
SELECT 'TRUE'
INTO strCustomer_exists
FROM PERSON
WHERE PERSON_ID = aRow.CUSTOMER_ID;
EXCEPTION
WHEN NO_DATA_FOUND THEN
strCustomer_exists := 'FALSE';
END;
IF strCustomer_exists = 'FALSE' THEN
DBMS_OUTPUT.PUT_LINE('Customer does not exist!');
END IF;
그러나 IMO는 비교적 느리고 오류가 발생하기 쉽습니다.이를 위해 IMO a Better Way(tm; IMO a Better Way)를 메인 커서에 포함합니다.
FOR aRow IN (SELECT i.*, p.ID AS PERSON_ID
FROM INVOICES i
LEFT OUTER JOIN PERSON p
ON (p.ID = i.CUSTOMER_PERSON_ID)
WHERE DUE_DATA < TRUNC(SYSDATE)-60)
LOOP
-- Check to see if the customer exists in PERSON
IF aRow.PERSON_ID IS NULL THEN
DBMS_OUTPUT.PUT_LINE('Customer does not exist!');
END IF;
END LOOP;
이 코드는 Person에 의존합니다.ID는 Person의 Primary Key(또는 적어도 NULL이 아님)로 선언됩니다.Person 테이블이 쿼리에 외부 결합되어 있고 PERCON_ID가 NULL로 표시되는 경우 PERTON으로 인해 특정 CUSTOMER_ID에 대한 행이 발견되지 않았음을 의미합니다.ID에는 값이 있어야 합니다(즉, NOT NULL 이상).
공유하고 즐기세요.
이 고양이의 가죽을 벗기는 데는 여러 가지 방법이 있다.각 테이블의 패키지에 간단한 기능을 넣었습니다.
function exists( id_in in yourTable.id%type ) return boolean is
res boolean := false;
begin
for c1 in ( select 1 from yourTable where id = id_in and rownum = 1 ) loop
res := true;
exit; -- only care about one record, so exit.
end loop;
return( res );
end exists;
수표도 깔끔하게...
IF pkg.exists(someId) THEN
...
ELSE
...
END IF;
select nvl(max(1), 0) from mytable;
이 문은 행이 없는 경우 0, 테이블에 행이 하나 이상 있는 경우 1이 됩니다.선택 카운트(*)보다 훨씬 빠릅니다.옵티마이저는 질문에 답하기 위해 하나의 행만 가져오면 된다는 것을 "인식"합니다.
다음은 (자세히) 작은 예입니다.
declare
YES constant signtype := 1;
NO constant signtype := 0;
v_table_has_rows signtype;
begin
select nvl(max(YES), NO)
into v_table_has_rows
from mytable -- where ...
;
if v_table_has_rows = YES then
DBMS_OUTPUT.PUT_LINE ('mytable has at least one row');
end if;
end;
명시적 커서를 사용하는 경우 다음과 같습니다.
DECLARE
CURSOR get_id IS
SELECT id
FROM person
WHERE id = 10;
id_value_ person.id%ROWTYPE;
BEGIN
OPEN get_id;
FETCH get_id INTO id_value_;
IF (get_id%FOUND) THEN
DBMS_OUTPUT.PUT_LINE('Record Found.');
ELSE
DBMS_OUTPUT.PUT_LINE('Record Not Found.');
END IF;
CLOSE get_id;
EXCEPTION
WHEN no_data_found THEN
--do things when record doesn't exist
END;
수 있다EXISTS
Oracle PL/SQL을 사용합니다.
다음을 수행할 수 있습니다.
DECLARE
n_rowExist NUMBER := 0;
BEGIN
SELECT CASE WHEN EXISTS (
SELECT 1
FROM person
WHERE ID = 10
) THEN 1 ELSE 0 INTO n_rowExist END FROM DUAL;
IF n_rowExist = 1 THEN
-- do things when it exists
ELSE
-- do things when it doesn't exist
END IF;
END;
/
설명:
에서(SELECT CASE WHEN EXISTES)SELECT 1 FROM person WHERE ID = 10
는합니다).값 않을 경우 값하여 값 1을 할당합니다.0으로 하다n_rowExist
않으면 0 = false가 .그 후 if 문은 반환된 값이 1과 동일한지 여부를 확인합니다.0 = 1 = 1 = 거짓이다.
Select 'YOU WILL SEE ME' as ANSWER from dual
where exists (select 1 from dual where 1 = 1);
Select 'YOU CAN NOT SEE ME' as ANSWER from dual
where exists (select 1 from dual where 1 = 0);
Select 'YOU WILL SEE ME, TOO' as ANSWER from dual
where not exists (select 1 from dual where 1 = 0);
select max( 1 )
into my_if_has_data
from MY_TABLE X
where X.my_field = my_condition
and rownum = 1;
모든 기록을 반복하지 않습니다.
[MY_TAB]의 경우LE에 데이터가 없으면 my_if_has_data가 null로 설정됩니다.
언급URL : https://stackoverflow.com/questions/21140868/proper-way-of-checking-if-row-exists-in-table-in-pl-sql-block
'programing' 카테고리의 다른 글
Meteor Publish/Subscribe 이해 (0) | 2023.03.10 |
---|---|
AngularJS: 컨트롤러와 서비스 (0) | 2023.03.05 |
스프링 부트 java.langNoClassDefFoundError: javax/servlet/Filter (0) | 2023.03.05 |
JSON은 ""로 시작할 수 있습니까? (0) | 2023.03.05 |
Angular 2에서 클릭 시 이벤트를 호출합니다. (0) | 2023.03.05 |