web-dev-qa-db-fra.com

Quel est le moyen le plus efficace de vérifier si un enregistrement existe dans Oracle?

UNE) 

select decode(count(*), 0, 'N', 'Y') rec_exists
from (select 'X'
      from dual
      where exists (select 'X'
                    from sales
                    where sales_type = 'Accessories'));

B)

select decode(count(*), 0, 'N', 'Y') rec_exists
from (select 'X'
      from sales
      where sales_type = 'Accessories'); 

C) Quelque chose d'autre (spécifiez)

EDIT: Il était difficile de choisir la réponse "correcte", car la meilleure approche dépend de ce que vous voulez faire après avoir vérifié si la valeur existe, comme l'a souligné APC. J'ai finalement choisi la réponse de RedFilter, car j'avais initialement envisagé cette vérification comme une fonction à part entière.

34
Zesty
select case 
            when exists (select 1 
                         from sales 
                         where sales_type = 'Accessories') 
            then 'Y' 
            else 'N' 
        end as rec_exists
from dual;
70
RedFilter

Quelle est la logique sous-jacente que vous souhaitez implémenter? Si, par exemple, vous souhaitez vérifier l’existence d’un enregistrement pour déterminer l’insertion ou la mise à jour, le meilleur choix serait d’utiliser MERGE à la place.

Si vous vous attendez à ce que le disque existe la plupart du temps, c'est probablement le moyen le plus efficace de procéder (même si la solution CASE WHEN EXISTS est susceptible d'être tout aussi efficace): 

begin
    select null into dummy
    from sales
    where sales_type = 'Accessories'
    and rownum = 1;

    --  do things here when record exists
    ....        

exception
    when no_data_found then
        -- do things here when record doesn't exists
        .....
end;

Vous n’avez besoin de la ligne ROWNUM que si SALES_TYPE n’est pas unique. Il ne sert à rien de faire un compte lorsque tout ce que vous voulez savoir, c'est s'il existe au moins un enregistrement. 

13
APC
select count(1) into existence 
   from sales where sales_type = 'Accessories' and rownum=1;

Le plan Oracle indique qu'il en coûte 1 si la colonne seles_type est indexée.

8
tyger

ici, vous pouvez uniquement vérifier y, n .__ si nous devons également sélectionner un nom, que ce nom existe ou non.

select name , decode(count(name),0, 'N', 'Y')
  from table
 group by name;

Ici, quand c’est Y seulement, il retournera la sortie, sinon il donnera toujours la valeur null. C’est ainsi que les enregistrements n’existant pas avec N comme dans la sortie, nous obtiendrons Name, N. Lorsque name n’existe pas dans la table

1
Aashish
select NVL ((select 'Y' from  dual where exists
   (select  1 from sales where sales_type = 'Accessories')),'N') as rec_exists
from dual

La table 1.Dual retournera «Y» si l'enregistrement existe dans la table sales_type La table 2.Dual retournera la valeur null si aucun enregistrement n'existe dans la table sales_type et NVL le convertira en «N»

0
Awknewbie

Le moyen le plus efficace et le plus sûr de déterminer l'existence d'une ligne consiste à utiliser un FOR-LOOP ... Vous n'aurez même pas de difficulté à insérer une ligne ou à faire quelque chose en fonction de la ligne être là, mais cela vous aidera certainement si vous devez déterminer s’il existe une rangée. Voir exemple de code ci-dessous pour les entrées et sorties ...

Si vous souhaitez uniquement savoir qu’un seul enregistrement existe dans votre ensemble de rendements multiples potentiels, vous pouvez quitter votre boucle après qu’elle le frappe pour la première fois. 

La boucle ne sera pas entrée du tout s'il n'y a pas d'enregistrement. Vous ne recevrez aucune plainte d'Oracle ou autre si la ligne n'existe pas, mais vous êtes tenu de savoir si cela se produit malgré tout. C'est ce que j'utilise 90% du temps (bien sûr, cela dépend de mes besoins) ...

EXEMPLE: 

DECLARE

v_exist varchar2(20);

BEGIN
   FOR rec IN
   (SELECT LOT, COMPONENT 
   FROM TABLE
   WHERE REF_DES = (SELECT REF_DES FROM TABLE2 WHERE ORDER = '1234') 
   AND ORDER = '1234')
  LOOP

      v_exist := "IT_EXISTS"

   INSERT INTO EAT_SOME_SOUP_TABLE (LOT, COMPONENT) 
   VALUES (rec.LOT, rec.COMPONENT);**

   --Since I don't want to do this for more than one iteration (just in case there may have been more than one record returned, I will EXIT;

   EXIT;
   END LOOP;



IF v_exist  IS NULL

    THEN

            --do this

END IF;

END;

- C'est en dehors de la boucle, ici Le IF-CHECK juste au-dessus s'exécutera indépendamment, mais vous saurez alors si votre variable est nulle ou incorrecte.?. S'il n'y avait AUCUN enregistrement, il sautera la boucle et ira simplement ici au code que vous auriez ensuite ... Si (dans notre cas ci-dessus), 4 enregistrements étaient renvoyés, je sortirais après la première itération en raison de mon EXIT ; ... Si ce n’était pas là, les 4 enregistrements seraient parcourus et insérés dans chacun d’eux. Ou du moins essayer aussi.

Au fait, je ne dis pas que c’est la seule façon d’envisager de le faire ... Vous pouvez 

SELECT COUNT(*) INTO v_counter WHERE ******* etc...

Puis vérifie comme  

if v_counter > 0
      THEN
         --code goes here
   END IF;

Il y a plus de moyens ... Déterminez-le quand votre besoin s'en fait sentir. Gardez à l’esprit la performance et la sécurité.

0
Jeremy
select CASE 
when exists (SELECT U.USERID,U.USERNAME,U.PASSWORDHASH
FROM  TBLUSERS U WHERE U.USERID =U.USERID 
AND U.PASSWORDHASH=U.PASSWORDHASH) 
then 'OLD PASSWORD EXISTS' 
else 'OLD PASSWORD NOT EXISTS' 
end as OUTPUT
from DUAL;
0
nofil qureshi
select decode(count(*), 0, 'N', 'Y') rec_exists 
      from sales 
      where sales_type = 'Accessories'; 
0
Randy