Pl / SQL проблема с синтаксисом в коде проверки - PullRequest
0 голосов
/ 09 января 2020

При попытке написать сценарий такого типа в PL / SQL во второй строке с «WHEN» я получаю синтаксическую ошибку. Пожалуйста, помогите Функция должна проверять и содержать логи c, которые она пытается написать

У меня нет большого опыта. Как я мог написать это по-другому?

create or replace FUNCTION BUSINESS_PROVIDER_GET(valueGet IN VARCHAR2)
    RETURN VARCHAR2
    IS
      v_value business_provider_configuration.billing_account_id%TYPE ;
    BEGIN
    DECLARE
            V_BUSINESS_PROVIDER  business_provider_configuration.business_provider%TYPE; 
            V_TRADING_NAME   business_provider_configuration.trading_name%TYPE; 
            V_CUSTOMER_ID business_provider_configuration.customer_id%TYPE;
            V_PROVIDER BUSINESS_PROVIDER_CONFIGURATION%TYPE;

    BEGIN
            SELECT
            *
            INTO V_BUSINESS_PROVIDER
            FROM
            BUSINESS_PROVIDER_CONFIGURATION
            WHERE 
            V_BUSINESS_PROVIDER = valueGet
            AND
            Upper(V_BUSINESS_PROVIDER) = Upper (valueGet);
            EXCEPTION
            WHEN no_data_found THEN

            SELECT
            *
            INTO V_TRADING_NAME
            FROM
            BUSINESS_PROVIDER_CONFIGURATION
            WHERE 
            V_TRADING_NAME = valueGet
            AND
            Upper(V_TRADING_NAME) = Upper (valueGet);
            EXCEPTION
            WHEN no_data_found THEN

            SELECT
            *
            INTO V_CUSTOMER_ID
            FROM
            BUSINESS_PROVIDER_CONFIGURATION
            WHERE 
            V_CUSTOMER_ID = valueGet
            AND
            Upper(V_CUSTOMER_ID) = Upper (valueGet);

            EXCEPTION
            WHEN no_data_found
            raise_application_error(-20000, 'Not found');

Ответы [ 2 ]

3 голосов
/ 09 января 2020

Исключением является ключевое слово «конец блока» - вы не можете просто вытащить его из ниоткуда несколько раз в одном и том же блоке.

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

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

Это очень помогает исправить такое проблемы при правильном отступе кода - я должен был сделать это здесь:

create or replace FUNCTION BUSINESS_PROVIDER_GET(valueGet IN VARCHAR2)
    RETURN VARCHAR2
    IS
        v_value business_provider_configuration.billing_account_id%TYPE ;
    BEGIN
    DECLARE
        V_BUSINESS_PROVIDER  business_provider_configuration.business_provider%TYPE; 
        V_TRADING_NAME   business_provider_configuration.trading_name%TYPE; 
        V_CUSTOMER_ID business_provider_configuration.customer_id%TYPE;
        V_PROVIDER BUSINESS_PROVIDER_CONFIGURATION%TYPE;
    BEGIN
        SELECT *
          INTO V_BUSINESS_PROVIDER
          FROM BUSINESS_PROVIDER_CONFIGURATION
         WHERE V_BUSINESS_PROVIDER = valueGet
           AND Upper(V_BUSINESS_PROVIDER) = Upper (valueGet);
    EXCEPTION
        WHEN no_data_found THEN
            BEGIN -- Block that can raise second exception
                SELECT *
                  INTO V_TRADING_NAME
                  FROM BUSINESS_PROVIDER_CONFIGURATION
                 WHERE V_TRADING_NAME = valueGet
                   AND Upper(V_TRADING_NAME) = Upper (valueGet);
            EXCEPTION
            WHEN no_data_found THEN
                BEGIN -- Block that can raise third exception
                    SELECT *
                      INTO V_CUSTOMER_ID
                      FROM BUSINESS_PROVIDER_CONFIGURATION
                     WHERE V_CUSTOMER_ID = valueGet
                       AND Upper(V_CUSTOMER_ID) = Upper (valueGet);
                EXCEPTION
                    WHEN no_data_found
                        raise_application_error(-20000, 'Not found');
                END; -- End of block that can raise third exception
            END; -- End of block that can raise second exception
    END BUSINESS_PROVIDER_GET; -- End of function body

У меня нет ваших таблиц, поэтому я не смог его протестировать, здесь все еще могут быть некоторые проблемы.

Кроме того, в коде немного путаницы - вам не нужно искать в нескольких столбцах, имеющих различное деловое значение, только одно значение.

И я понятия не имею, как вы хотите » выберите * 'в единственную скалярную переменную из таблицы, которая имеет несколько столбцов - просто укажите, какой столбец вы хотите получить. Я бы сказал, что 'select *' никогда не должен использоваться в хранимом коде, если только вы не извлекаете переменную записи, которая наследует тип строки из таблицы.

1 голос
/ 09 января 2020

Прежде всего, условия, которые вы используете, никогда не будут возвращать никаких значений. Вы определяете переменную, например, V_BUSINESS_PROVIDER, и сразу после этого сравниваете ее со значением valueGet. Так как V_BUSINESS_PROVIDER равен нулю, результат условий всегда будет ложным

Во-вторых, набор условий

V_BUSINESS_PROVIDER = valueGet
AND Upper(V_BUSINESS_PROVIDER) = Upper(valueGet);

является избыточным. Если вам нужно, чтобы значения были в одном и том же регистре (например, «Слово» <> «СЛОВО»), вы должны использовать только строки, подобные этой

V_BUSINESS_PROVIDER = valueGet

, в противном случае, если вам не нужно сравнивать регистры ( например, «Слово» = «СЛОВО») вам нужно использовать только такие условия

AND Upper(V_BUSINESS_PROVIDER) = Upper(valueGet)

В-третьих. Как я вижу, цель состоит в том, чтобы получить значения столбцов в переменные, названные в их честь. В этом случае вы должны указать имена столбцов в операторе выбора. Например,

select business_provider
  into V_BUSINESS_PROVIDER
  FROM BUSINESS_PROVIDER_CONFIGURATION
....

В-четвертых, использование обработчиков исключений для неуправляемых целей - плохая идея. Я бы порекомендовал вам переписать эту часть следующим образом

create or replace FUNCTION BUSINESS_PROVIDER_GET(valueGet IN VARCHAR2) 
RETURN VARCHAR2
IS
v_value business_provider_configuration.billing_account_id%TYPE ;
V_BUSINESS_PROVIDER  business_provider_configuration.business_provider%TYPE; 
V_TRADING_NAME   business_provider_configuration.trading_name%TYPE; 
V_CUSTOMER_ID business_provider_configuration.customer_id%TYPE;
V_PROVIDER BUSINESS_PROVIDER_CONFIGURATION%TYPE;
BEGIN
  begin
    select ... into V_BUSINESS_PROVIDER ...;
  exception 
    when no_data_found then 
      V_BUSINESS_PROVIDER := null;
  end;

  if V_BUSINESS_PROVIDER is null then
    begin
      select ... into V_TRADING_NAME ...;
    exception 
      when no_data_found then 
        V_TRADING_NAME := null;
    end;
  end if;

  if V_TRADING_NAME is null then
    begin
      select ... into V_CUSTOMER_ID ...;
    exception 
      when no_data_found then 
        raise(...); -- though I'm not sure if you have to raise it, the no_data_found will get raised anyway you can handle the native exception
    end;
  end if;
end BUSINESS_PROVIDER_GET;
...