2010-08-08 3 views
28

)Каков наиболее эффективный способ проверить, существует ли запись в Oracle?

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) Что-то другое (указать)

EDIT: Это было трудно выбрать "правильный" ответ, как лучший подход зависит от что вы хотите сделать после проверки, существует ли это значение, как указано APC. Я закончил тем, что выбрал ответ RedFilter, так как я первоначально предполагал эту проверку как функцию сам по себе.

+0

(Очень старый вопрос, я знаю ...) Иногда мне нужно сделать простую проверку для «это действительный идентификационный номер» (то есть он уже существует) из серверной программы (PHP), поэтому я в итоге делаю простой SQL-запрос: 'SELECT null FROM table_name WHERE id =: id' (с использованием подготовленных операторов,': id'). Если какие-либо строки были возвращены, ответ будет да. В противном случае нет. Фактические возвращенные данные неактуальны. – user128216

ответ

60
select case 
      when exists (select 1 
         from sales 
         where sales_type = 'Accessories') 
      then 'Y' 
      else 'N' 
     end as rec_exists 
from dual; 
+1

Выглядит неплохо. Благодаря! – Zesty

+5

Вам не хватает 'FROM dual'. –

+0

Спасибо, я исправил это. – RedFilter

0
select decode(count(*), 0, 'N', 'Y') rec_exists 
     from sales 
     where sales_type = 'Accessories'; 
-3
SELECT 'Y' REC_EXISTS    
FROM SALES      
WHERE SALES_TYPE = 'Accessories' 

Результат будет либо 'Y' или NULL. Простой тест против 'Y'

+2

Результат будет «Y», если существует одна запись. Если существует несколько записей, это будет исключение TOO_MANY_ROWS. Если записей нет, это будет исключение NO_DATA_FOUND. – APC

+0

@APC: Нет, если вы не выбрали одну переменную. Запрос, написанный, является чистым SQL и не вызывает никаких исключений. – ObiWanKenobi

+2

@ObiWanKenobi - как вы тестируете значение, если не выбрали его в переменной? – APC

13

Какова основная логика, которую вы хотите реализовать? Если, например, вы хотите проверить наличие записи, чтобы определить, как вставить или обновить, лучшим выбором было бы вместо этого использовать MERGE.

Если вы планируете запись на существование большую часть времени, это, пожалуй, самый эффективный способ делать вещи (хотя CASE WHEN EXISTS решение может быть столь же эффективным):

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; 

Вам нужно только строка ROWNUM, если SALES_TYPE не уникален. Нет смысла делать счет, когда все, что вы хотите знать, есть ли, по крайней мере, одна запись.

+1

+1 Хороший ответ. Я часто использую этот чек в разных обстоятельствах ... вот почему мне было интересно, как лучше всего это сделать. Иногда я просто хочу вернуть флаг в переднюю часть. В других случаях я делаю что-то другое, например, возвращаю значение, если оно существует, а если нет, возвращаем следующее значение последовательности. Я думаю, вы правы - лучший способ может зависеть от ситуации. – Zesty

1

здесь вы можете проверить только y, n , если нам нужно также указать имя, независимо от того, существует ли это имя или нет.

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

Здесь, когда это Y, тогда он будет возвращать выход, иначе он будет давать null всегда. Whts тыс способ получить записи не существует с N, как на выходе мы получим имя, N. Если имя не существует в таблице

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

план Oracle говорит, что это стоит 1, если столбец seles_type индексируется.

+7

Это метод, который я обычно использую, но count (1) действительно должен быть count (\ *) - нет ничего особенного в count (1), а count (\ *) - стандартный синтаксис. –

+1

count (1) означает, что мы считаем, что ничего не существует. По-моему, читать легче. – tyger

+1

Вот что значит count (\ *).В этом контексте «\ *» не означает «все столбцы» в том смысле, что он делает в «select \ * from» –

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

1.Dual таблица будет возвращать «Y», если запись существует в sales_type таблице 2.Dual таблица будет возвращать нулевое значение, если запись не существует в sales_type таблице и NVL преобразует что «N»

+0

Пожалуйста, добавьте некоторое объяснение в свой ответ, чтобы поддержать ваш код. – Rachcha

0

Самый эффективный и безопасный способ определить, существует ли строка, с помощью FOR-LOOP ... Вам даже не будет сложного времени, если вы хотите вставить строку или сделать что-то на основе строки НЕ но это, безусловно, поможет вам, если вам нужно определить, существует ли строка. См. Пример кода ниже для входов и выходов ...

Если вас интересует только то, что в вашем потенциальном множественном наборе ответов существует 1 запись, вы можете выйти из цикла после того, как она впервые попадает в нее.

Петля вообще не вводится, если запись не существует. Вы не получите никаких жалоб от Oracle или таких, если строка не существует, но вы обязательно узнаете, что она делает независимо.Это то, что я использую 90% времени (конечно, в зависимости от моих потребностей) ...

Пример:

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; 

--This находится вне петли прямо здесь IF-CHECK чуть выше будет запустите независимо, но тогда вы узнаете, является ли ваша переменная нулевой или неправильной!?. Если бы не было никаких возвращенных записей, он пропустил бы цикл и просто перешел сюда к следующему коду ... Если (в нашем случае выше), было возвращено 4 записи, я бы вышел после первой итерации из-за моего EXIT ; ... Если этого не было, 4 записи будут проходить через и вставлять их во все. Или, по крайней мере, попробуйте тоже.

Кстати, я не говорю, что это единственный способ, которым Вы должны рассмотреть делать это ... Вы можете

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

Затем проверьте его как

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

Там больше способов ... Просто определите, когда возникнет ваша потребность. Помните о производительности и безопасности.

-1

Просто введите счетчик (ы), который вы ищете. Если count> 0, то запись (записи) существует.

 
    DECLARE 
    rec_count NUMBER := 0; 

    BEGIN 

    select count(*) 
    into rec_count 
    from EMPLOYEETABLE 
    WHERE employee_id = inEMPLOYEE_ID 
    AND department_nbr = inDEPARTMENT_NBR; 


    if rec_count > 0 then 
     {UPDATE EMPLOYEETABLE} 
    else 
     {INSERT INTO EMPLOYEETABLE} 
    end if; 

    END; 
Смежные вопросы