Создайте столбец и добавьте в него данные с помощью программы PL / SQL. - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь создать программу на PL / SQL, в которой я добавляю столбец (называемый AGE_GROUP) в таблицу, а затем вставляю данные в этот столбец, но, похоже, он не работает.

    DECLARE
    cust_age string(10);
    cust_inc string(10);
    cust_status string(10);
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10));';
    FOR emp IN (SELECT *
                FROM datacopy) LOOP
        cust_age := get_group_age(emp.ID);
        cust_inc := get_income_level(emp.ID);
        cust_status := fix_status(emp.ID);
      UPDATE datacopy SET AGE_GROUP = cust_age WHERE ID = emp.ID;
      UPDATE datacopy SET INCOME_LEVEL = cust_inc WHERE ID = emp.ID;
      UPDATE datacopy SET MARITAL_STATUS = cust_status WHERE ID = emp.ID;
      COMMIT;
    END LOOP;
END; 

Я вижу сообщение об ошибке - ORA-06550: строка 12, столбец 27: PL / SQL: ORA-00904: «AGE_GROUP»: недопустимый идентификатор

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Как сказал @Maxim, в момент разбора блока PL / SQL в таблице нет столбца AGE_GROUP, поэтому

UPDATE datacopy SET AGE_GROUP = cust_age WHERE ID = emp.ID;

выдает ошибку ORA-00904, которую вы видите. Вы должны сделать это обновление также динамическим, например ::10000

EXECUTE IMMEDIATE 'UPDATE datacopy SET AGE_GROUP = :1 WHERE ID = :2' USING cust_age, emp.ID;

Но ваш запрос курсора также будет иметь проблему, потому что во время выполнения, которое больше не соответствует определению таблицы во время компиляции - поэтому SELECT * теперь возвращает больше столбцов, чем ожидалось. (Ошибка от этого ORA-00932.)

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

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

DECLARE
    cust_age string(10);
    cust_inc string(10);
    cust_status string(10);
BEGIN
    EXECUTE IMMEDIATE 'ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10))';
    FOR emp IN (SELECT ID
                FROM datacopy) LOOP
        cust_age := get_group_age(emp.ID);
        cust_inc := get_income_level(emp.ID);
        cust_status := fix_status(emp.ID);
        EXECUTE IMMEDIATE 'UPDATE datacopy SET AGE_GROUP = :cust_age WHERE ID = :id'
          USING cust_age, emp.ID;
        UPDATE datacopy SET INCOME_LEVEL = cust_inc WHERE ID = emp.ID;
        UPDATE datacopy SET MARITAL_STATUS = cust_status WHERE ID = emp.ID;
        COMMIT;
    END LOOP;
END;
/

Однако существует ряд других проблем с этим кодом. Использование string(10) в качестве типа данных для ваших локальных переменных не очень Oracle-y, и они не всегда могут быть строками - вы можете использовать %TYPE для столбцов, которые уже существуют в таблице. Вы не должны совершать внутри цикла. И вы делаете три отдельных обновления одной и той же строки, что кажется расточительным, когда вы можете установить все три значения столбца одновременно - с помощью одного динамического оператора:

EXECUTE IMMEDIATE 'UPDATE datacopy SET AGE_GROUP = :cust_age,'
  || ' INCOME_LEVEL = :cust_inc,'
  || ' MARITAL_STATUS = :cust_status'
  || ' WHERE ID = :id'
  USING cust_age, cust_inc, cust_status, emp.ID;

Конечно, было бы проще сделать ALTER как простой оператор SQL перед блоком PL / SQL, а не внутри него.

Не похоже, что вам действительно нужен PL / SQL или циклический переход по строкам; Вы можете сделать одно статическое обновление после статического изменения:

ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10));

UPDATE datacopy SET AGE_GROUP = get_group_age(ID),
  INCOME_LEVEL = get_income_level(ID),
  MARITAL_STATUS = fix_status(ID);
0 голосов
/ 10 января 2019

Это потому, что блок анализируется первым и только потом выполняется, если ошибок нет. Вы получаете ошибку синтаксического анализа, потому что в таблице анализа данных нет столбца age_group во время анализа. Вы должны попробовать использовать динамический SQL, ref курсор.

И удалите одну из двоеточий, должно быть следующее:

EXECUTE IMMEDIATE 'ALTER TABLE DATACOPY ADD(AGE_GROUP VARCHAR2(10))';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...