КАСКАДНОЕ УДАЛЕНИЕ только однажды

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

175
задан Community 23 May 2017 в 12:26
поделиться

4 ответа

Нет. Сделать это просто, как только Вы просто записали бы оператор удаления для таблицы, которую Вы хотите расположить каскадом.

DELETE FROM some_child_table WHERE some_fk_field IN (SELECT some_id FROM some_Table);
DELETE FROM some_table;
153
ответ дан palehorse 23 November 2019 в 20:27
поделиться

Если я понимаю правильно, необходимо быть в состоянии сделать то, что Вы хотите путем отбрасывания ограничения внешнего ключа, добавления нового (который расположится каскадом), делая материал, и воссоздавая ограничение внешнего ключа ограничения.

, Например:

testing=# create table a (id integer primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "a_pkey" for table "a"
CREATE TABLE
testing=# create table b (id integer references a);
CREATE TABLE

-- put some data in the table
testing=# insert into a values(1);
INSERT 0 1
testing=# insert into a values(2);
INSERT 0 1
testing=# insert into b values(2);
INSERT 0 1
testing=# insert into b values(1);
INSERT 0 1

-- restricting works
testing=# delete from a where id=1;
ERROR:  update or delete on table "a" violates foreign key constraint "b_id_fkey" on table "b"
DETAIL:  Key (id)=(1) is still referenced from table "b".

-- find the name of the constraint
testing=# \d b;
       Table "public.b"
 Column |  Type   | Modifiers 
--------+---------+-----------
 id     | integer | 
Foreign-key constraints:
    "b_id_fkey" FOREIGN KEY (id) REFERENCES a(id)

-- drop the constraint
testing=# alter table b drop constraint b_a_id_fkey;
ALTER TABLE

-- create a cascading one
testing=# alter table b add FOREIGN KEY (id) references a(id) on delete cascade; 
ALTER TABLE

testing=# delete from a where id=1;
DELETE 1
testing=# select * from a;
 id 
----
  2
(1 row)

testing=# select * from b;
 id 
----
  2
(1 row)

-- it works, do your stuff.
-- [stuff]

-- recreate the previous state
testing=# \d b;
       Table "public.b"
 Column |  Type   | Modifiers 
--------+---------+-----------
 id     | integer | 
Foreign-key constraints:
    "b_id_fkey" FOREIGN KEY (id) REFERENCES a(id) ON DELETE CASCADE

testing=# alter table b drop constraint b_id_fkey;
ALTER TABLE
testing=# alter table b add FOREIGN KEY (id) references a(id) on delete restrict; 
ALTER TABLE

, Конечно, необходимо абстрагировать материал как этот в процедуру ради психического здоровья.

17
ответ дан Ryszard Szopa 23 November 2019 в 20:27
поделиться

Удаление с каскадной опцией только относилось к таблицам с определенными внешними ключами. Если Вы сделаете удаление, и оно говорит, что Вы не можете, потому что оно нарушило бы ограничение внешнего ключа, каскад заставит его удалять незаконные строки.

, Если Вы хотите удалить связанные строки таким образом, необходимо будет определить внешние ключи сначала. Кроме того, помните, если Вы явно не даете ему команду начинать транзакцию, или изменение значений по умолчанию это сделает автоматическую фиксацию, которая могла быть очень трудоемкой для чистки.

1
ответ дан Grant Johnson 23 November 2019 в 20:27
поделиться

Если вы действительно хотите DELETE FROM some_table CASCADE; , что означает « удалить все строки из таблицы some_table », вы можете использовать ] TRUNCATE вместо DELETE и CASCADE всегда поддерживается. Однако, если вы хотите использовать выборочное удаление с предложением , где , TRUNCATE недостаточно.

ИСПОЛЬЗУЙТЕ С ЗАБОТОЙ - это приведет к удалению всех строк всех таблиц с ограничением внешнего ключа для some_table и всех таблиц с ограничениями для этих таблиц и т. д.

Postgres поддерживает CASCADE с командой TRUNCATE :

TRUNCATE some_table CASCADE;

К счастью, это транзакция (то есть с возможностью отката), хотя он не полностью изолирован от других параллельных транзакций и имеет несколько других предостережений. Подробнее читайте в документации.

42
ответ дан 23 November 2019 в 20:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: