Как переименовать ограничение по умолчанию для Oracle?

88
6

Я хочу переименовать множество ограничений (PK, FK,... и т.д.), Которые имеют имена по умолчанию, которые начинаются с "SYS", чтобы иметь возможность вставлять одни и те же данные в другую БД.

Я нашел следующий сценарий, который я изменил, чтобы получить то, что хочу:

BEGIN
FOR cn IN (
SELECT constraint_name
FROM user_constraints
WHERE constraint_type = 'P'
AND table_name = 'SPECIALITE'
)
LOOP
EXECUTE IMMEDIATE 'ALTER TABLE ' || cn.table_name || ' RENAME CONSTRAINT ' || cn.constraint_name || ' TO PK_' || 'SPECIALITE';
END LOOP;
END;

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

ALTER TABLE 'SPECIALITE' RENAME CONSTRANT (....)

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

Является ли это возможным?

спросил(а) 2021-01-25T20:17:29+03:00 4 месяца, 3 недели назад
1
Решение
89

Как вы уже знаете, вам нужно запустить два запроса.

select constraint_name from user_constraints 
where table_name = <table_name> and constraint_type = 'P';

и с именем ограничения в руке,

alter table <table_name> rename constraint <old_constr_name> to <new_constr_name>;

Для этого потребуется скопировать имя ограничения из первого запроса и вставить его во второй, в нужном месте (<old_constr_name>).

Если бы это все, я бы не отправил ответ. Но я помню кое-что, что я прочитал на AskTom некоторое время назад - умный способ избежать копирования и вставки, используя команду COLUMN в SQL * Plus. (Это может также работать в SQL Developer и Toad.) Что-то вроде этого:

column constraint_name new_val c   -- Note: no semicolon - this is SQL*Plus, not SQL

select constraint_name from user_constraints
where table_name = <table_name> and constraint_type = 'P';

alter table <table_name> rename constraint &c to <new_constr_name>;

Если вам нужно изменить многие имена ограничений PK, это сэкономит некоторую работу. Имя ограничения, возвращаемое запросом SELECT, сохраняется в "new_val" с надписью "c" из команды SQL * Plus COLUMN и используется в инструкции ALTER TABLE.

ответил(а) 2021-01-25T20:17:29+03:00 4 месяца, 3 недели назад
45

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

select 'ALTER TABLE ' || table_name || ' RENAME CONSTRAINT ' || constraint_name || ' TO PK_' || upper( table_name )
from user_constraints
where constraint_type = 'P'
and constraint_name like 'SYS%';

Этот select отобразит все таблицы с ограничением на свой первичный ключ, который начинается с "SYS" и переименовывает его в PK_TABLE_NAME;

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

Вы также можете использовать созданный столбец, подобный этому

select 'ALTER TABLE ' || table_name || ' RENAME CONSTRAINT ' || constraint_name || ' TO PK_' || upper( table_name )
from user_constraints
where constraint_type = 'P'
and generated = 'GENERATED NAME';

но у вас будут таблицы BIN и, возможно, другие нежелательные таблицы

ответил(а) 2021-01-25T20:17:29+03:00 4 месяца, 3 недели назад
45

Добавьте представление user_cons_columns к вашему SQL, чтобы вы могли генерировать имена ограничений. Вот быстрый и грязный пример:

select 'ALTER TABLE ' || c.table_name || ' RENAME CONSTRAINT ' || c.constraint_name  || ' TO ' || substr(c.constraint_type || '_' || c.table_name || '_' || replace(wm_concat(cc.column_name), ',', '_'), 0, 30) || ';'
from user_constraints c
join user_cons_columns cc on c.table_name = cc.table_name and c.constraint_name = cc.constraint_name
where c.constraint_name like 'SYS%'
group by c.table_name, c.constraint_name, c.constraint_type;

Этот SQL генерирует исполняемый скрипт с такими командами:

ALTER TABLE TABLENAME RENAME CONSTRAINT SYS_xxxxxx TO C_TABLENAME_COLUMN;

Обратите внимание, что я использую недокументированную функцию wm_concat. Если вы используете Oracle> = 11g, вместо этого используйте listagg.

ответил(а) 2021-01-25T20:17:29+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема