Làm cách nào để sử dụng TẠO HOẶC THAY THẾ?


98

Tôi có đúng khi hiểu rằng CREATE OR REPLACE về cơ bản có nghĩa là "nếu đối tượng tồn tại, hãy thả nó, sau đó tạo nó theo cách nào đó?"

Nếu vậy, tôi đang làm gì sai? Những công việc này:

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

Và điều này không (ORA-00922: tùy chọn bị thiếu hoặc không hợp lệ):

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

Tôi đang làm điều gì đó ngu ngốc? Tôi dường như không thể tìm thấy nhiều tài liệu về cú pháp này.

Câu trả lời:


153

Điều này hoạt động trên các hàm, thủ tục, gói, loại, từ đồng nghĩa, trình kích hoạt và chế độ xem.

Cập nhật:

Sau khi cập nhật bài đăng lần thứ ba, tôi sẽ định dạng lại:

Điều này không hoạt động trên bảng :)

Và có, có tài liệu về cú pháp này, và không có REPLACEtùy chọn cho CREATE TABLE.


33

Một trong những điều thú vị về cú pháp là bạn có thể chắc chắn rằng a CREATE OR REPLACEsẽ không bao giờ khiến bạn mất dữ liệu (thứ mà bạn sẽ mất nhiều nhất là mã, hy vọng rằng bạn sẽ được lưu trữ trong kiểm soát nguồn ở đâu đó).

Cú pháp tương đương cho các bảng là ALTER, có nghĩa là bạn phải liệt kê rõ ràng những thay đổi được yêu cầu.

CHỈNH SỬA: Nhân tiện , nếu bạn cần thực hiện DROP + CREATE trong tập lệnh và bạn không quan tâm đến lỗi "đối tượng không tồn tại" giả mạo (khi DROP không tìm thấy bảng), bạn có thể thực hiện điều này:

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

23

Không có bảng tạo hoặc thay thế trong Oracle.

Bạn phải:

DROP TABLE foo;
TẠO BẢNG foo (....);

10

CREATE OR REPLACE chỉ có thể được sử dụng trên các hàm, thủ tục, kiểu, dạng xem hoặc gói - nó sẽ không hoạt động trên bảng.


1
CREATE OR REPLACEcũng làm việc cho các từ đồng nghĩa và trigger
Richard Mitchell

4

Tập lệnh sau sẽ thực hiện thủ thuật trên Oracle:

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

3

Không hoạt động với Bảng, chỉ có chức năng, v.v.

Đây là một trang web với một số ví dụ .


3

Một thủ tục hữu ích cho cơ sở dữ liệu oracle mà không cần sử dụng ngoại lệ (trong các trường hợp, bạn phải thay thế user_tables bằng dba_tables và / hoặc giới hạn vùng bảng trong truy vấn):

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

Một mã ít hơn ví dụ khác mà còn rõ ràng hơn một chút hơn trong mục đích của nó
Grokster

1

Nếu bạn đang làm trong mã thì trước tiên hãy kiểm tra bảng trong cơ sở dữ liệu bằng cách sử dụng truy vấn SELECT table_name FROM user_tables WHERE table_name = 'XYZ'

nếu bản ghi được tìm thấy thì hãy cắt ngắn bảng nếu không thì hãy tạo Bảng

Làm việc như Tạo hoặc Thay thế.


1

Bạn có thể sử dụng CORT ( www.softcraftltd.co.uk/cort ). Công cụ này cho phép TẠO HOẶC THAY THẾ bảng trong Oracle. Nó có vẻ như:

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

Nó bảo tồn dữ liệu.


1

Vì vậy, tôi đã sử dụng nó và nó đã hoạt động rất tốt: - nó hoạt động giống như một DROP NẾU TỒN TẠI nhưng hoàn thành công việc

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

Hy vọng điều này sẽ giúp Cũng tham khảo: Lỗi PLS-00103 trong PL / SQL Developer


1

Không thể tạo hoặc thay thế bảng. Như những người khác đã nêu, bạn có thể viết một thủ tục và / hoặc sử dụng begin execute ngay (...). Vì tôi không thấy câu trả lời về cách (lại) tạo bảng, tôi đã đặt một tập lệnh làm câu trả lời.

Tái bút: theo đúng những gì jeffrey-kemp đã đề cập: tập lệnh bên dưới này sẽ KHÔNG lưu dữ liệu đã có trong bảng mà bạn sắp xóa. Do nguy cơ mất dữ liệu, tại công ty chúng tôi, chỉ được phép thay đổi các bảng hiện có trên môi trường sản xuất, và không được phép bỏ bảng. Bằng cách sử dụng câu lệnh drop table, sớm muộn gì bạn cũng sẽ có được cảnh sát công ty đứng tại bàn làm việc của bạn.

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

Bạn có cần nhất quán với A_TABLE_EXAMPLE và A_TABLE_X không?
Jonathan Leffler

0

Tôi sẽ làm một cái gì đó như thế này

  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

Nếu đây là dành cho MS SQL .. Mã sau sẽ luôn chạy bất kể điều gì nếu bảng đã tồn tại hay chưa.

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
Xin lỗi, nhưng đây là Oracle. :-)
Jason Baker

comment "// có dữ liệu trong bảng" có chính xác không?
Jeffrey Kemp

xin lỗi tốt hơn một chút, object_id kiểm tra xem bảng có tồn tại trong db hay không. nó sẽ nói // bảng đã được tạo sẵn trong db
JuniorFlip
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.