CREATE OR REPLACE'i nasıl kullanırım?


102

YARATIN VEYA DEĞİŞTİRİN'in temelde "nesne varsa, bırakın, sonra her iki şekilde de oluşturun" anlamına geldiğini anlamakta haklı mıyım?

Eğer öyleyse, neyi yanlış yapıyorum? Bu çalışıyor:

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

Ve bu (ORA-00922: eksik veya geçersiz seçenek):

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

Aptalca bir şey mi yapıyorum? Bu sözdizimi hakkında çok fazla belge bulamıyorum.

Yanıtlar:


156

Bu, işlevler, prosedürler, paketler, türler, eşanlamlılar, tetikleyici ve görünümler üzerinde çalışır.

Güncelleme:

Gönderiyi üçüncü kez güncelledikten sonra, bunu yeniden biçimlendireceğim:

Bu tablolarda çalışmaz :)

Ve evet, bu sözdizimiyle ilgili belgeler var ve için herhangi bir REPLACEseçenek yok CREATE TABLE.


33

Sözdizimi ile ilgili güzel şeylerden biri, a'nın CREATE OR REPLACEasla veri kaybetmenize neden olmayacağından emin olabilmenizdir (en çok kaybedeceğiniz kod, umarız bir yerde kaynak kontrolünde saklamış olursunuz).

Tablolar için eşdeğer sözdizimi ALTER'dir; bu, gerekli olan tam değişiklikleri açıkça numaralandırmanız gerektiği anlamına gelir.

DÜZENLEME: Bu arada, bir komut dosyasında DROP + CREATE yapmanız gerekiyorsa ve sahte "nesne yok" hatalarını umursamıyorsanız (DROP tabloyu bulamadığında) bu:

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

24

Oracle'da tablo oluşturma veya değiştirme yoktur.

Mecbursun:

DROP TABLE foo;
CREATE TABLE foo (....);

11

CREATE OR REPLACE yalnızca işlevler, prosedürler, türler, görünümler veya paketlerde kullanılabilir - tablolarda çalışmaz.


1
CREATE OR REPLACEaynı zamanda eşanlamlılar ve tetikleyiciler için de çalışıyor
Richard Mitchell

4

Aşağıdaki komut dosyası Oracle'da hile yapmalıdır:

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


3

İstisnaları kullanmadan oracle veritabanları için faydalı bir prosedür (koşullar altında user_tables'ı dba_tables ile değiştirmeniz ve / veya sorgudaki tablo alanını kısıtlamanız gerekir):

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;
/

Diğer örneklerden biraz daha fazla kod ama aynı zamanda amacında biraz daha net
grokster

1

Kod içinde yapıyorsanız, önce SELECT table_name sorgusunu kullanarak veritabanında tabloyu kontrol edin FROM user_tables WHERE table_name = 'XYZ'

kayıt bulunursa, tabloyu kesin, aksi takdirde Tablo oluşturun

Yarat veya Değiştir gibi çalışın.


1

CORT'u ( www.softcraftltd.co.uk/cort ) kullanabilirsiniz . Bu araç, Oracle'da tablo OLUŞTURMA VEYA DEĞİŞTİRME sağlar. Şöyle görünüyor:

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

Verileri korur.


1

Bunu kullanıyorum ve çok iyi çalıştı: - daha çok bir DROP IF EXISTS gibi çalışıyor ama işi hallediyor

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;
/   

Umarım bu yardımcı olur Ayrıca referans: PLS-00103 PL / SQL Developer'da Hata


1

'Tablo oluşturma veya değiştirme' mümkün değildir. Başkalarının da belirttiği gibi, bir prosedür yazabilir ve / veya hemen çalıştırmaya başlayabilirsiniz (...). Tablonun nasıl (yeniden) oluşturulacağına dair bir cevap göremediğim için, cevap olarak bir komut dosyası koydum.

Not: jeffrey-kemp'in bahsettiği doğrultusunda: betiğin altındaki bu, bırakacağınız tabloda zaten mevcut olan verileri KAYDETMEYECEKTİR. Şirketimizde veri kaybı riski nedeniyle üretim ortamında sadece mevcut tabloların değiştirilmesine izin verilmekte, tabloların düşürülmesine izin verilmemektedir. Açılır masa ifadesini kullanarak, er ya da geç şirket polisinin masanızda durmasını sağlayacaksınız.

--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;

A_TABLE_EXAMPLE ve A_TABLE_X ile tutarlı olmanız gerekiyor mu?
Jonathan Leffler

0

Böyle bir şey yapardım

  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

Bu MS SQL içinse .. Aşağıdaki kod, tablo zaten mevcut olsa da olmasa da her zaman çalışacaktır.

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
Üzgünüm ama bu Oracle. :-)
Jason Baker

"// Tabloda veri var mı" yorumu doğru mu?
Jeffrey Kemp

üzgünüm biraz daha iyi, object_id tablonun veritabanında var olup olmadığını kontrol eder. o masa db zaten oluşturulmuş // demeliyim
JuniorFlip
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.