2015-02-05 2 views
0

У меня есть процедура Что такое обновление моих клиентов с данными из другой таблицы. И некоторые клиенты не обновляются по причине отказа одного из своих значений.как проверить значение перед обновлением в процедуре plsql

Это ошибка, которая вызывает: ORA - 12899: значение слишком велико для столбца «TABLE_EXAMPLE» «BRANCH_CODE» (текущий: 3, максимум: 2).

И теперь это процедура:

PROCEDURE p_update_customers AS 

CURSOR customer_data IS 
    SELECT a.code_cust code_cust, 
     '0' || a.branch_code branch_code, 
     a.costumer_id, 
     a.name name, 
     b.description 
    FROM customer a, description b 
    WHERE a.costumer_id = b.costumer_id; 

reg_customer_data customer_data%ROWTYPE; 

BEGIN 
BEGIN 
    OPEN customer_data; 
    LOOP 
    FETCH customer_data 
     INTO reg_customer_data; 
    EXIT WHEN customer_data%NOTFOUND; 
    BEGIN 

Я думаю, что в этой части я должен проверить ветвь кода с помощью IF или CASE-заявления. Мне нужны только две последние цифры значения. (Между BEGIN и UPDATE).

UPDATE table_example 
     SET code_cust  = reg_customer_data.code_cust, 
      branch_code = reg_customer_data.branch_code, 
      costumer_id = reg_customer_data.costumer_id, 
      name   = reg_customer_data.name, 
      description = reg_customer_data.description 
     WHERE code_cust  = reg_customer_data.code_cust; 
    END; 
    END LOOP; 
END; 
END p_update_customers; 

Таким образом, мне нужно проверить branch_code перед обновлением, потому что мне нужно только две последние цифры (09 или 58).

costumer_id name  branch_code 
    1   jose  09 
    2   peter  09 
    3   jhon  09 
    4   charlie 058 

Если branch_code имеет 3 цифры, удалить первый и передать значение 2 цифры, а затем продолжить обновление.

Примечание: я не могу изменить или удалить конкат, который я использую в курсоре: CUSTOMER_DATA, потому что BRANCH_CODE на TABLE_EXAMPLE должен быть двухзначным.

ответ

1

Если вы не можете изменить курсор, вы можете по-прежнему использовать отрицательное значение позиции с the substr() function посчитать в обратном направлении от конца строки, как показал Ed Гиббс, но и против результирующего набора курсора:

with t as (
    select 1 as costumer_id, 'jose' as name, '09' as branch_code from dual 
    union all select 2, 'peter ', '09' from dual 
    union all select 3, 'jhon', '09' from dual 
    union all select 4, 'charlie', '058' from dual 
) 
select costumer_id, name, branch_code, 
    substr(branch_code, -2) as new_branch_code 
from t; 

| COSTUMER_ID | NAME | BRANCH_CODE | NEW_BRANCH_CODE | 
|-------------|---------|-------------|-----------------| 
|   1 | jose |   09 |    09 | 
|   2 | peter |   09 |    09 | 
|   3 | jhon |   09 |    09 | 
|   4 | charlie |   058 |    58 | 

SQL Fiddle.

Таким образом, вы можете изменить свое обновление, чтобы установить значение, используя один и тот же вызов:

UPDATE table_example 
     SET code_cust  = reg_customer_data.code_cust, 
      branch_code = substr(reg_customer_data.branch_code, -2), 
... 
2

Заменить '0' || a.branch_code branch_code с одним из следующих способов в зависимости от типа customer.branch_code данных ...

  • Если это числовая:

    TO_CHAR(a.branch_code, 'FM00') branch_code 
    
  • Если это VARCHAR/varchar2:

    SUBSTR('0' || a.branch_code, -2, 2) branch_code 
    

Добавление: OP отметил, что курсор не может быть изменен, поэтому решение должно быть сдвинуто на обновление:

UPDATE table_example 
    SET code_cust  = reg_customer_data.code_cust, 
     branch_code = SUBSTR(reg_customer_data.branch_code, -2, 2), 
     costumer_id = reg_customer_data.costumer_id, 
     name   = reg_customer_data.name, 
     description = reg_customer_data.description 
    WHERE code_cust  = reg_customer_data.code_cust; 
+0

Благодарим за вашу помощь, но косяк Прикоснитесь к CUSTOMER_DATA курсора. – spikeTJ

+1

@harsd - см. Добавление к моему ответу, которое изменяет 'UPDATE' и оставляет курсор в покое; надеюсь, что это сработает для вас. –