Eu tenho um banco de dados que tem uma restrição NOT NULL em um campo e desejo remover essa restrição. O fator complicador é que essa restrição tem um nome definido pelo sistema e o nome dessa restrição difere entre o servidor de produção, o servidor de integração e os vários bancos de dados do desenvolvedor. Nosso processo atual é fazer o check-in dos scripts de alteração e uma tarefa automatizada executa as consultas apropriadas por meio do sqlplus no banco de dados de destino, então eu preferiria uma solução que pudesse ser enviada diretamente para o sqlplus.
Em meu próprio banco de dados, o SQL para eliminar isso seria:
alter table MYTABLE drop constraint SYS_C0044566
Posso ver a restrição ao consultar a all_constraints
visualização:
select * from all_constraints where table_name = 'MYTABLE'
mas não tenho certeza de como trabalhar com o SEARCH_CONDITION
's LONG
tipo de dados ou a melhor forma de eliminar de forma dinâmica a restrição olhou-up, mesmo depois de eu sei o seu nome.
Portanto, como posso criar um script de mudança que possa eliminar essa restrição com base no que ela é, em vez de em seu nome?
EDIT: @A resposta de Allan é boa, mas estou preocupado (em minha falta de experiência em Oracle) que pode não ser universalmente verdadeiro que qualquer restrição que possa ter um nome gerado pelo sistema terá associado a ele uma maneira de remover o restrição sem precisar saber seu nome. É verdade que sempre haverá uma maneira de evitar ter que saber o nome de uma restrição nomeada pelo sistema ao eliminar logicamente essa restrição?
fonte
Respostas:
alter table MYTABLE modify (MYCOLUMN null);
No Oracle, as restrições não nulas são criadas automaticamente quando não nulo é especificado para uma coluna. Da mesma forma, eles são eliminados automaticamente quando a coluna é alterada para permitir nulos.
Esclarecendo a questão revisada : Esta solução se aplica apenas a restrições criadas para colunas "não nulas". Se você especificar "Chave primária" ou uma restrição de verificação na definição da coluna sem nomeá-la, você terminará com um nome gerado pelo sistema para a restrição (e o índice, para a chave primária). Nesses casos, você precisa saber o nome para descartá-lo. O melhor conselho é evitar o cenário, certificando-se de especificar um nome para todas as restrições, exceto "não nulo". Se você se encontrar na situação em que precisa descartar uma dessas restrições genericamente, provavelmente precisará recorrer à PL / SQL e às tabelas de definição de dados.
fonte
not null
restrições são as únicas com nome de sistema em meu esquema que provavelmente me afetarão dessa forma.Experimentar:
alter table <your table> modify <column name> null;
fonte
Apenas lembre-se, se o campo que você deseja tornar nulo fizer parte de uma chave primária, você não pode. As chaves primárias não podem ter campos nulos.
fonte
Para descobrir quaisquer restrições usadas, use o código abaixo:
-- Set the long data type for display purposes to 500000. SET LONG 500000 -- Define a session scope variable. VARIABLE output CLOB -- Query the table definition through the <code>DBMS_METADATA</code> package. SELECT dbms_metadata.get_ddl('TABLE','[Table Described]') INTO :output FROM dual;
Isso mostra essencialmente uma instrução de criação de como a tabela referenciada é feita. Ao saber como a tabela é criada, você pode ver todas as restrições da tabela.
Resposta retirada do blog de Michael McLaughlin: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ De sua classe Database Design I.
fonte
Eu estava enfrentando o mesmo problema ao tentar contornar uma restrição de verificação personalizada que precisava atualizar para permitir valores diferentes. O problema é que ALL_CONSTRAINTS não tem uma maneira de dizer a qual coluna as restrições são aplicadas. A forma como consegui fazer isso é consultando ALL_CONS_COLUMNS, em seguida, descartando cada uma das restrições por seu nome e recriá-lo.
selecione constraint_name de all_cons_columns onde table_name = [TABLE_NAME] e column_name = [COLUMN_NAME];
fonte
Algo assim aconteceu comigo quando fiz cópias de estruturas para tabelas temporárias, então removi o não nulo.
DECLARE CURSOR cur_temp_not_null IS SELECT table_name, constraint_name FROM all_constraints WHERE table_name LIKE 'TEMP_%' AND owner='myUSUARIO'; V_sql VARCHAR2(200); BEGIN FOR c_not_null IN cur_temp_not_null LOOP v_sql :='ALTER TABLE ' || c_not_null.table_name || ' DROP CONSTRAINT '|| c_not_null.constraint_name; EXECUTE IMMEDIATE v_sql; END LOOP; END;
fonte
Se a restrição na coluna STATUS foi criada sem um nome durante a criação de uma tabela, o Oracle atribuirá um nome aleatório para ela. Infelizmente, não podemos modificar a restrição diretamente.
Etapas envolvidas para eliminar a restrição sem nome vinculada à coluna STATUS
Renomear STATUS2 para STATUS
ALTER TABLE MY_TABLE ADD STATUS2 NVARCHAR2(10) DEFAULT 'OPEN'; ALTER TABLE MY_TABLE ADD CONSTRAINT MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED')); UPDATE MY_TABLE SET STATUS2 = STATUS; ALTER TABLE MY_TABLE DROP COLUMN STATUS; ALTER TABLE MY_TABLE RENAME COLUMN STATUS2 TO STATUS;
fonte