Como faço para usar CREATE OR REPLACE?


98

Estou correto em entender que CREATE OR REPLACE basicamente significa "se o objeto existe, elimine-o e crie-o de qualquer maneira?"

Se sim, o que estou fazendo de errado? Isso funciona:

CREATE TABLE foo (id NUMBER,
title VARCHAR2(4000) DEFAULT 'Default Title')

E isso não acontece (ORA-00922: opção ausente ou inválida):

CREATE OR REPLACE TABLE foo (id NUMBER,
title VARCHAR2(4000) DEFAULT 'Default Title')

Estou fazendo algo estúpido? Não consigo encontrar muita documentação sobre essa sintaxe.

Respostas:


153

Isso funciona em funções, procedimentos, pacotes, tipos, sinônimos, gatilho e visualizações.

Atualizar:

Depois de atualizar a postagem pela terceira vez, vou reformular isso:

Isso não funciona em tabelas :)

E sim, há documentação sobre essa sintaxe e não há REPLACEopção para ela CREATE TABLE.


33

Uma das coisas boas sobre a sintaxe é que você pode ter certeza de que a CREATE OR REPLACEnunca causará a perda de dados (o máximo que você perderá é o código, que espero ter armazenado no controle de origem em algum lugar).

A sintaxe equivalente para tabelas é ALTER, o que significa que você deve enumerar explicitamente as mudanças exatas que são necessárias.

EDIT: A propósito, se você precisa fazer um DROP + CREATE em um script, e você não liga para os erros espúrios "objeto não existe" (quando o DROP não encontra a mesa), você pode fazer isto:

BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE owner.mytable';
EXCEPTION
  WHEN OTHERS THEN
    IF sqlcode != -0942 THEN RAISE; END IF;
END;
/

23

Não há criação ou substituição de tabela no Oracle.

Você deve:

DROP TABLE foo;
CRIAR TABELA foo (....);

10

CREATE OR REPLACE só pode ser usado em funções, procedimentos, tipos, visualizações ou pacotes - não funcionará em tabelas.


1
CREATE OR REPLACEtambém funciona para sinônimos e gatilhos
Richard Mitchell

4

O seguinte script deve fazer o truque no Oracle:

BEGIN
  EXECUTE IMMEDIATE 'drop TABLE tablename';
EXCEPTION
  WHEN OTHERS THEN
    IF sqlcode != -0942 THEN RAISE; 
    END IF;
END;


3

Um procedimento útil para bancos de dados Oracle sem usar exceções (sob circunstâncias, você deve substituir user_tables por dba_tables e / ou restringir o espaço de tabela na consulta):

create or replace procedure NG_DROP_TABLE(tableName varchar2)
is
   c int;
begin
   select count(*) into c from user_tables where table_name = upper(tableName);
   if c = 1 then
      execute immediate 'drop table '||tableName;
   end if;
end;

3
-- To Create or Replace a Table we must first silently Drop a Table that may not exist
DECLARE
  table_not_exist EXCEPTION;
  PRAGMA EXCEPTION_INIT (table_not_exist , -00942);
BEGIN
   EXECUTE IMMEDIATE('DROP TABLE <SCHEMA>.<TABLE NAME> CASCADE CONSTRAINTS');
   EXCEPTION WHEN table_not_exist THEN NULL;
END;
/

Um pouco mais de código do que outros exemplos, mas também um pouco mais claro em sua finalidade
grokster

1

Se você estiver fazendo em código, primeiro verifique a tabela no banco de dados usando a consulta SELECT nome_tabela FROM tabelas_usuario WHERE nome_tabela = 'XYZ'

se o registro for encontrado, truncar a tabela, caso contrário, criar a tabela

Trabalhe como Criar ou Substituir.


1

Você pode usar o CORT ( www.softcraftltd.co.uk/cort ). Esta ferramenta permite CRIAR OU REPLACE tabela no Oracle. Parece:

create /*# or replace */ table MyTable(
  ... -- standard table definition
);

Ele preserva os dados.


1

Estou usando isso e funcionou muito bem: - funciona mais como um DROP IF EXISTS, mas dá conta do recado

DECLARE
       VE_TABLENOTEXISTS EXCEPTION;
PRAGMA EXCEPTION_INIT(VE_TABLENOTEXISTS, -942);


    PROCEDURE DROPTABLE(PIS_TABLENAME IN VARCHAR2) IS
              VS_DYNAMICDROPTABLESQL VARCHAR2(1024);
                    BEGIN
                       VS_DYNAMICDROPTABLESQL := 'DROP TABLE ' || PIS_TABLENAME;  
                    EXECUTE IMMEDIATE VS_DYNAMICDROPTABLESQL;

                    EXCEPTION
                        WHEN VE_TABLENOTEXISTS THEN
                             DBMS_OUTPUT.PUT_LINE(PIS_TABLENAME || ' NOT EXIST, SKIPPING....');
                        WHEN OTHERS THEN
                             DBMS_OUTPUT.PUT_LINE(SQLERRM);
                    RAISE;
                    END DROPTABLE;

    BEGIN
      DROPTABLE('YOUR_TABLE_HERE');
END DROPTABLE;
/   

Espero que isso ajude Também referência: PLS-00103 Erro no PL / SQL Developer


1

'Criar ou substituir tabela' não é possível. Como outros afirmaram, você pode escrever um procedimento e / ou usar begin execute imediatamente (...). Como não vejo uma resposta sobre como (re) criar a tabela, coloquei um script como resposta.

PS: em linha com o que jeffrey-kemp mencionou: este script abaixo NÃO salvará dados que já estão presentes na tabela que você vai eliminar. Devido ao risco de perda de dados, em nossa empresa só é permitida a alteração de tabelas existentes no ambiente de produção, não sendo permitida a eliminação de tabelas. Ao usar o extrato da mesa suspensa, mais cedo ou mais tarde você colocará a polícia da empresa em pé na sua mesa.

--Create the table 'A_TABLE_X', and drop the table in case it already is present
BEGIN
EXECUTE IMMEDIATE 
'
CREATE TABLE A_TABLE_X
(
COLUMN1 NUMBER(15,0),
COLUMN2  VARCHAR2(255 CHAR),
COLUMN3  VARCHAR2(255 CHAR)
)';

EXCEPTION
WHEN OTHERS THEN
  IF SQLCODE != -955 THEN -- ORA-00955: object name already used
     EXECUTE IMMEDIATE 'DROP TABLE A_TABLE_X';
  END IF;
END;

Você precisa ser consistente com A_TABLE_EXAMPLE e A_TABLE_X?
Jonathan Leffler

0

Eu faria algo assim

  begin
     for i in (select table_name from user_tables where table_name = 'FOO') loop
        execute immediate 'drop table '||i.table_name;
     end loop;
  end;

  execute immediate 'CREATE TABLE FOO (id NUMBER,
                                       title VARCHAR2(4000)) ';

-4

Se for para MS SQL .. O código a seguir sempre será executado, não importa se a tabela já existe ou não.

if object_id('mytablename') is not null //has the table been created already in the db
Begin
     drop table mytablename
End

Create table mytablename (...

1
Desculpe, mas este é o Oracle. :-)
Jason Baker

o comentário "// há dados na tabela" é preciso?
Jeffrey Kemp

desculpe um pouco melhor, o object_id verifica se a tabela existe no banco de dados. deve dizer // a tabela já foi criada no banco de dados
JuniorFlip
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.