Операторы Oracle SQL*Plus ACCEPT

Мне нужна небольшая помощь с моим скриптом SQL*Plus. Могу ли я каким-либо образом сделать так, чтобы он принимал переменную, проверял таблицу на совпадение и, если находил ее, выходил из программы и не продолжал выполнять остальные операторы принятия?

У меня есть этот код до сих пор:

ACCEPT p_cname PROMPT 'Enter Customer Name: '
DECLARE
     v_cname CHAR(20);
BEGIN
     SELECT cname INTO v_cname
            FROM customer
     WHERE cname = '&p_cname';

     IF v_name = '&p_cname' THEN
            -- Exit the program
     END IF;
END;
/

-- Other ACCEPT statements if a match was not found.

Я не хочу, чтобы он продолжался с остальной частью программы, если совпадение найдено. Есть ли способ сделать это?


person Dan    schedule 29.07.2011    source источник
comment
Метка в последней строке + переход к метке?   -  person Sathyajith Bhat    schedule 29.07.2011


Ответы (5)


Вы можете сделать это, включив проверку ошибок, а затем вызвав сообщение об ошибке.

ACCEPT p_cname PROMPT 'Enter Customer Name: '

WHENEVER SQLERROR EXIT SUCCESS ROLLBACK;

DECLARE
     v_count  INTEGER;
BEGIN
     SELECT COUNT(*) INTO v_count
            FROM customer
     WHERE cname = '&p_cname';

     IF v_count > 0 THEN
            raise_application_error( -20100, 'Customer already exists' );
     END IF;

END;
/

-- Issue a new WHENEVER statement here if you want different error-handling for
-- the rest of the script

-- Other ACCEPT statements if a match was not found.

В команде WHENEVER ключевое слово SUCCESS означает, что SQLPlus вернет код успеха обратно в оболочку, из которой он был вызван. Вы также можете использовать FAILURE для возврата общего кода ошибки или другие параметры для возврата конкретных значений.

person Dave Costa    schedule 29.07.2011
comment
Я согласен. Я бы просто использовал count(*), чтобы избежать исключений No_data_found или too_many_rows. - person zep; 29.07.2011
comment
@zep - хорошая мысль! Как написано, это также приведет к завершению сценария, если клиент еще не существует, потому что запрос вызовет no_data_found. Я исправлю это. - person Dave Costa; 29.07.2011

С помощью команды whenever SQL*Plus , вы можете заставить SQL*Plus закрыться при возникновении ошибки в SQL или PL/SQL. Это означает, что все, что вам нужно сделать, это вызвать пользовательское исключение, чтобы заставить скрипт выйти.

WHENEVER SQLERROR EXIT;
ACCEPT p_cname PROMPT 'Enter Customer Name: '
DECLARE
     v_cname CHAR(20);
BEGIN
     SELECT cname INTO v_cname
            FROM customer
     WHERE cname = '&p_cname';

     IF v_name = '&p_cname' THEN
         raise_application_error(-2000,'Your error Message here');
     END IF;
END;
/
person Allan    schedule 29.07.2011

Быстрый ответ: «Не совсем». SQL*Plus — довольно простой клиент. Он может отправить запрос или блок PL/SQL на сервер и показать возвращаемый набор данных, но SQL*Plus (не SQL или PL/SQL) не имеет простых условных операторов, таких как IF или повторяющиеся структуры LOOP.

Вместо использования SQL*Plus вам следует рассмотреть язык сценариев, такой как Perl или Python.

person Gary Myers    schedule 29.07.2011
comment
Но так как вы можете запустить блок PL/SQL в SQL*Plus, вы можете использовать там конструкции IF. - person a_horse_with_no_name; 29.07.2011

Почему бы просто не переключить условие?

 IF v_name <> '&p_cname' THEN
        -- Do whatever you want
 END IF;

Таким образом, ничего не произойдет, если v_name действительно соответствует вводу, потому что нет части ELSE.

person a_horse_with_no_name    schedule 29.07.2011
comment
Потому что в этом случае он хочет сделать дополнительные операторы ACCEPT, которые не могут находиться внутри блока PL/SQL. - person Dave Costa; 29.07.2011

Гэри прав, вам нужно будет написать решение.

что-то подобное под линуксом

uid="userid"
pwd="password"
echo "enter name:"
read name

dbname=`sqlplus -s <<EOF
$uid/$pwd @part1.sql $name
EOF`

if [$dbname == $name ] 
then
    echo name found
    exit
fi

в вашем скрипте вы можете использовать &1 для получения входного параметра (я бы также ограничил результаты до 1), например:

set heading off
set pagesize 0
set tab off

SELECT cname
FROM customer
    WHERE cname = '&1' and rownum <2; 
/
exit
# add other reads & execure part2,3, etc
person Kevin Burton    schedule 29.07.2011