Есть ли способ проверить, удастся ли изменить столбец таблицы в SQL?

У меня есть инструмент, который вносит много изменений в базу данных. Многие изменения касаются изменения типов столбцов, размеров и т. д. Существует ли какой-либо (возможно, специфичный для Oracle) способ заранее определить, будет ли данное ALTER TABLE изменение успешным и не приведет ли к сбою из-за слишком длинных значений, функциональных индексов и т. д.?

С модификациями без DDL это просто: запустите транзакцию, выполните свои изменения и выполните откат. Ответ известен из того, получаете ли вы исключение или нет. Однако модификации DDL не могут быть частью транзакций, поэтому здесь я не могу следовать той же процедуре.


person doublep    schedule 03.06.2015    source источник
comment
Если DDL выйдет из строя, с ним будет связана ORA-ошибка. Вам нужно повторить попытку с необходимыми изменениями. Изменение таблицы — это не обычное дело, вы создаете таблицу один раз, а затем изменяете ее только тогда, когда это необходимо для бизнеса, и вам нужно пройти релиз, чтобы приложение не пострадало. Итак, мне интересно, как это поможет вам узнать до выполнения, будет ли DDL успешным или нет? Если ваш инструмент выполняет эти модификации, он должен обрабатывать их программно. Перед изменением проверьте тип и размер столбцов.   -  person Lalit Kumar B    schedule 03.06.2015
comment
@LalitKumarB: у меня есть сотни модификаций, и было бы полезно заранее сообщить, не сработает ли изменение № 62. т.е. прежде чем вы даже начнете с этого. Я понимаю, что могу сделать это программно, я просто подумал, что, возможно, есть более надежный способ опроса самой базы данных. Например. довольно неочевидно, как проверить наличие функциональных индексов в измененном столбце или определенных ограничениях.   -  person doublep    schedule 03.06.2015


Ответы (3)


Есть ли какой-либо (возможно, специфичный для Oracle) способ заранее узнать, будет ли данное изменение ALTER TABLE успешным и не завершится ошибкой из-за слишком длинных значений

Я бы сказал, что это не очень хороший дизайн, когда вам нужно создавать/изменять объекты базы данных на лету. При этом, если DDL дает сбой, с ним будет связана ORA-ошибка. Вам нужно повторить попытку с необходимыми изменениями. Изменение таблицы — это не обычное дело, вы создаете таблицу один раз, а затем изменяете ее только тогда, когда это необходимо для бизнеса, и вам нужно пройти выпуск, чтобы приложение не пострадало. Итак, мне интересно, как это поможет вам узнать до выполнения, будет ли DDL успешным или нет? Если ваш инструмент выполняет эти модификации, он должен обрабатывать их программно. Перед изменением проверьте тип и размер столбцов.

Если вы делаете это с помощью внешнего скрипта, вам нужно построить собственную логику. Вы можете использовать представления метаданных, такие как user_tab_columns, чтобы проверить data_type, data_size, data_precision, data_scale и т. д.

Небольшой пример логики проверки размера типа данных VARCHAR2 перед выполнением оператора ALTER (для демонстрации я делаю это на PL/SQL, вы можно применить аналогичную логику в вашем скрипте или инструменте):

SQL> CREATE TABLE t (A VARCHAR2(10));

Table created.

SQL> DESC t;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 A                                                  VARCHAR2(10)

SQL> SET serveroutput ON
SQL> DECLARE
  2    v_type   VARCHAR2(20);
  3    v_size   NUMBER;
  4    new_size NUMBER;
  5  BEGIN
  6    new_size:= 20;
  7    SELECT data_type,
  8      data_length
  9    INTO v_type,
 10      v_size
 11    FROM user_tab_columns
 12    WHERE table_name='T';
 13    IF v_type       ='VARCHAR2' THEN
 14      IF new_size   > v_size THEN
 15        EXECUTE IMMEDIATE 'ALTER TABLE T MODIFY A '||v_type||'('||new_size||')';
 16        DBMS_OUTPUT.PUT_LINE('Table altered successfully');
 17      ELSE
 18        DBMS_OUTPUT.PUT_LINE('New size should be greater than existing data size');
 19      END IF;
 20    END IF;
 21  END;
 22  /
Table altered successfully

PL/SQL procedure successfully completed.

Итак, таблица успешно изменена, давайте проверим:

SQL> DESC t;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 A                                                  VARCHAR2(20)

SQL>

Я видел несколько приложений, использующих скрипт groovy, который выполняет всю проверку и подготавливает операторы ALTER на основе проверок data_type, data_size, data_precision, data_scale и т. д.

Для разных проверок нужно добавить больше блоков IF-ELSE. Это был один из примеров увеличения размера типа данных VARCHAR2. Вам нужно создать исключение при уменьшении размера столбца, в зависимости от того, есть ли в столбце какие-либо существующие данные или нет... и так далее. .

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

Например,

Числовые типы:

CREATE OR REPLACE FUNCTION is_numeric (i_col_name)...
<using the above logic>
IF v_type       ='NUMBER' THEN
<do something>
RETURN 1;

Типы персонажей:

CREATE OR REPLACE FUNCTION is_string (i_col_name)...
<using the above logic>
IF v_type       ='VARCHAR2' THEN
<do something>
RETURN 1;
person Lalit Kumar B    schedule 03.06.2015

На ум приходят два подхода, ни один из которых на самом деле не дает вам того, чего вы хотите.

Во-первых, и я упоминаю об этом исключительно для того, чтобы описать, чего вы на самом деле хотите, а не потому, что это практично, это написать инструмент, который анализирует ваши изменения в сценарии SQL и применяет к объектам те же правила, что и Oracle, т.е. столбец - и проверьте, не превышают ли значения столбца новую длину. Это огромная задача, и когда вы считаете, что изменения будут каскадными/составными, вам также нужно учитывать это. Я бы также не ожидал, что это будет быстро - если вы измените неиндексированный столбец в таблице из x миллионов строк, инструмент должен будет сканировать данные, которые приведут к сбою изменения. Какая бы внутренняя магия ни использовалась Oracle для определения этого, она не будет доступна для этого инструмента.

Подход, который я использую, опять же не совсем то, что вам нужно, заключается в клонировании базы данных из рабочей среды с урезанными данными. В основном я делаю это с помощью сценариев, чтобы иметь контроль и не полагаться на специальные разрешения / доступ к базе данных. Затем я тестирую свои сценарии развертывания на соответствие этому и делаю это итеративно, пока не получу чистую сборку. Я использую структуру развертывания, которую я создал, которая имеет функцию перезапуска, поэтому, если развертывание завершается сбоем на шаге 63 из 121, он дает мне возможность повторить попытку/пропустить/прервать, а если я прерву его, он может перезапуститься с неудачного шага. Как только я доволен своей сборкой для разработчиков, я затем тестирую базу данных, которая синхронизирована с рабочей средой — это помогает сгладить проблемы с данными и/или производительностью.

Теперь, другой возможный способ для вас может состоять в том, чтобы взглянуть на воспоминания. Я не уверен, что flashback также обрабатывает DDL, но если это так, и при условии, что он включен в вашей базе данных dev/test (большое если), то это может быть тем, что стоит изучить.

person TenG    schedule 03.06.2015
comment
Теперь еще один возможный способ для вас - взглянуть на ретроспективный кадр. Ретроспективный кадр — это процесс после выполнения, и ОП хочет предварительную проверку, а не пост-восстановление. Кстати, да, FLASHBACK теперь поддерживает операторы DDL, такие как ALTER, учитывая, что вы используете версию 11gR2 и выше. См. мой ответ здесь stackoverflow.com/a/25950842/3989608 - person Lalit Kumar B; 03.06.2015

Попробуйте мой инструмент CORT — www.softcraftltd.co.uk/cort

Это бесплатно и с открытым исходным кодом. Возможно, вы найдете там то, что вам нужно.

person Rusty    schedule 03.06.2015