Як мені використовувати СТВОРИТИ АБО ЗАМІНИТИ?


98

Чи правильно я розумію, що CREATE OR REPLACE в основному означає "якщо об'єкт існує, скиньте його, а потім створіть у будь-який спосіб?"

Якщо так, то що я роблю неправильно? Це працює:

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

І це не робить (ORA-00922: відсутній або недійсний варіант):

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

Я роблю щось дурне? Здається, я не можу знайти багато документації щодо цього синтаксису.

Відповіді:


154

Це працює над функціями, процедурами, пакетами, типами, синонімами, тригером та поданнями.

Оновлення:

Після оновлення посади втретє я переформулюю це:

Це не працює на таблицях :)

І так, є документація на цей синтаксис, і немає жодної REPLACEопції для CREATE TABLE.


33

Одна з приємних речей щодо синтаксису - це те, що ви можете бути впевнені, що a CREATE OR REPLACEніколи не призведе до втрати даних (найбільше ви втратите - це код, який, сподіваємось, ви десь збереглися в контролі джерела).

Еквівалентний синтаксис для таблиць - ALTER, що означає, що вам потрібно явно перерахувати точні зміни, які потрібні.

РЕДАГУВАТИ: До речі, якщо вам потрібно зробити DROP + CREATE у сценарії, і вам байдужі помилкові помилки "об'єкт не існує" (коли DROP не знаходить таблиці), ви можете зробити це:

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

23

У Oracle немає таблиці створення або заміни.

Ти повинен:

DROP TABLE foo;
СТВОРИТИ ТАБЛИЦЮ foo (....);

10

CREATE OR REPLACE можна використовувати лише для функцій, процедур, типів, представлень даних або пакетів - це не працюватиме на таблицях.


1
CREATE OR REPLACEтакож працює для синонімів та тригерів
Річард Мітчелл

4

Наступний сценарій повинен зробити фокус для Oracle:

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


3

Корисна процедура для баз даних oracle без використання винятків (за обставин вам доведеться замінити user_tables на dba_tables та / або обмежити табличний простір у запиті):

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

Трохи більше коду, ніж інші приклади, але також трохи більш чітке за своїм призначенням
grokster

1

Якщо ви робите код, то спочатку перевірте таблицю в базі даних, використовуючи запит SELECT table_name FROM user_tables WHERE table_name = 'XYZ'

якщо запис знайдено, тоді обрізану таблицю інакше створіть таблицю

Робота, як створити або замінити.


1

Ви можете використовувати CORT ( www.softcraftltd.co.uk/cort ). Цей інструмент дозволяє створити та замінити таблицю в Oracle. Це виглядає як:

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

Він зберігає дані.


1

Тож я використовую це, і він спрацював дуже добре: - Він працює більше, як ДРОП, АБО Є, але виконує роботу

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

Сподіваюся, що це допомагає Також довідка: PLS-00103 Помилка PL / SQL Developer


1

'Створити або замінити таблицю' неможливо. Як заявляли інші, ви можете написати процедуру та / або використовувати негайно розпочати виконання (...). Оскільки я не бачу відповіді, як (повторно) створити таблицю, я поставив сценарій як відповідь.

PS: відповідно до того, що згадував jeffrey-kemp: цей сценарій НЕ зберігатиме дані, які вже є у таблиці, яку ви збираєтеся викинути. Через ризик втрати даних в нашій компанії дозволяється лише змінювати існуючі таблиці на виробничому середовищі, і забороняється скидати таблиці. Скориставшись заявою про випадання таблиці, рано чи пізно ви отримаєте поліцію компанії, яка стоїть за вашим столом.

--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 та A_TABLE_X?
Джонатан Леффлер

0

Я б зробив щось подібне

  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

Якщо це для MS SQL .. Наступний код завжди буде працювати незалежно від того, існувала таблиця вже чи ні.

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
Вибачте, але це Oracle. :-)
Джейсон Бейкер,

чи правильним є коментар "// чи є дані в таблиці"?
Джеффрі Кемп,

вибачте трохи краще, object_id перевіряє, чи існує таблиця в базі даних. слід сказати // чи таблиця створена вже в базі даних
JuniorFlip
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.