16.05.2020 20:May
Задача: иметь в нескольких таблицах общий уникальный для *всех* таблиц (не для каждой отдельно, с этим справится просто `UNIQUE`) `INTEGER`.
Допустим, в одной таблице есть две записи с идентификаторами (не `rowid`) 1 и 2, я хочу при добавлении двух записей в другую таблицу получить 3 и 4 (если в запросе не указано иного) для этих новых записей, а при добавлении ещё двух в третью — 5 и 6, ну и при добавлении снова в первую — 7 и 8 и так далее.
*// MySQL, Postgres и прочие тоже годятся, мне бы только понять что искать.*
Допустим, в одной таблице есть две записи с идентификаторами (не `rowid`) 1 и 2, я хочу при добавлении двух записей в другую таблицу получить 3 и 4 (если в запросе не указано иного) для этих новых записей, а при добавлении ещё двух в третью — 5 и 6, ну и при добавлении снова в первую — 7 и 8 и так далее.
*// MySQL, Postgres и прочие тоже годятся, мне бы только понять что искать.*
• Правила форума
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
18.05.2020 01:May
Довольно странная хотелка, но можно сделать на триггерах (SQLite3) как-то так:
```sql
CREATE TABLE "glob" (
"id" INTEGER NOT NULL PRIMARY KEY,
"gid" INTEGER NOT NULL UNIQUE DEFAULT 1
);
CREATE TABLE "first_rel" (
"id" INTEGER NOT NULL PRIMARY KEY,
"gid" INTEGER DEFAULT NULL,
"data" TEXT NOT NULL
);
CREATE TABLE "second_rel" (
"id" INTEGER NOT NULL PRIMARY KEY,
"gid" INTEGER DEFAULT NULL,
"data" TEXT NOT NULL
);
CREATE TRIGGER "first_rel_glob_inc"
AFTER INSERT ON "first_rel" WHEN NEW."gid" IS NULL
BEGIN
UPDATE "first_rel"
SET "gid" = (SELECT "gid" FROM "glob" ORDER BY "id" LIMIT 1) WHERE "id" = NEW."id";
UPDATE "glob" SET "gid" = "gid" + 1;
END;
CREATE TRIGGER "second_rel_glob_inc"
AFTER INSERT ON "second_rel" WHEN NEW."gid" IS NULL
BEGIN
UPDATE "second_rel"
SET "gid" = (SELECT "gid" FROM "glob" ORDER BY "id" LIMIT 1) WHERE "id" = NEW."id";
UPDATE "glob" SET "gid" = "gid" + 1;
END;
INSERT INTO "glob" ("gid") VALUES (1);
```
И получился какой-то кошмар. Но можно же %).
```sql
CREATE TABLE "glob" (
"id" INTEGER NOT NULL PRIMARY KEY,
"gid" INTEGER NOT NULL UNIQUE DEFAULT 1
);
CREATE TABLE "first_rel" (
"id" INTEGER NOT NULL PRIMARY KEY,
"gid" INTEGER DEFAULT NULL,
"data" TEXT NOT NULL
);
CREATE TABLE "second_rel" (
"id" INTEGER NOT NULL PRIMARY KEY,
"gid" INTEGER DEFAULT NULL,
"data" TEXT NOT NULL
);
CREATE TRIGGER "first_rel_glob_inc"
AFTER INSERT ON "first_rel" WHEN NEW."gid" IS NULL
BEGIN
UPDATE "first_rel"
SET "gid" = (SELECT "gid" FROM "glob" ORDER BY "id" LIMIT 1) WHERE "id" = NEW."id";
UPDATE "glob" SET "gid" = "gid" + 1;
END;
CREATE TRIGGER "second_rel_glob_inc"
AFTER INSERT ON "second_rel" WHEN NEW."gid" IS NULL
BEGIN
UPDATE "second_rel"
SET "gid" = (SELECT "gid" FROM "glob" ORDER BY "id" LIMIT 1) WHERE "id" = NEW."id";
UPDATE "glob" SET "gid" = "gid" + 1;
END;
INSERT INTO "glob" ("gid") VALUES (1);
```
И получился какой-то кошмар. Но можно же %).
18.05.2020 09:May
XRevan86 post_id=817 time=1589764384 user_id=76 Написал:Довольно странная хотелка
Теперь я понимаю, что это плохая идея (плюс на триггерах это скажется на отзывчивости).
XRevan86 post_id=817 time=1589764384 user_id=76 Написал:```sql
UPDATE "first_rel"
SET "gid" = (SELECT "gid" FROM "glob" LIMIT 1) WHERE "id" = NEW."id";
```
Зачем здесь `SELECT` с `LIMIT 1`? Без `ORDER BY "gid" DESC` оно всегда выдаст первый (с `id=1`) gid, разве нет?
• Правила форума
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
18.05.2020 17:May
Цитата: Теперь я понимаю, что это плохая идея (плюс на триггерах это скажется на отзывчивости).
Ещё какая. И плохо связывается с теорией отношений.
Цитата: Зачем здесь ```SELECT``` с ```LIMIT 1```? Без ```ORDER BY "gid" DESC``` оно всегда выдаст первый (с id=1) gid, разве нет?
Эм, что? Он выдаст все записи.
Их, правда, и так должна быть только одна штука, но всё равно все.
А сортировка на размер выдачи не влияет никак.
18.05.2020 19:May
XRevan86 post_id=825 time=1589823073 user_id=76 Написал:Эм, что? Он выдаст все записи.
Я что-то проглядел, что у тебя там только одна запись, и ты её инкрементишь. У меня мозг пухнет от всего этого, поэтому я либо туплю, либо *сильно* туплю.
XRevan86 post_id=825 time=1589823073 user_id=76 Написал:Их, правда, и так должна быть только одна штука, но всё равно все.
Цитата: ```sqlSELECT "gid" FROM "glob" LIMIT 1;
```
Сколько бы ни было, `LIMIT 1` ограничит выдачу первым одним результатом. Без прочих условий это будет наименьший `PRIMARY KEY` (в данном случае `id=1`). Это не имеет значения если запись всего одна, но имеет смысл накатить условий, чтобы не отстрелить себе что-нибудь, если в таблицу прилетит ещё запись с `PRIMARY KEY` меньше существующего, например `0`, так как сортировка идёт по нему.
• Правила форума
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
19.05.2020 00:May
Цитата: Сколько бы ни было, ```LIMIT 1``` ограничит выдачу первым одним результатом.
Да я в курсе, я же сам его туда и вписал %).
Это было всё ещё про "Он выдаст все записи".
А, теперь я понял, что ты имел в виду.
SQLite не выдаст ошибку, если подзапрос даст больше одного кортежа, о сём я не вспомнил.
Цитата: Зачем здесь ```SELECT``` с ```LIMIT 1```?
В иной СУБД иначе могла бы быть ошибка в случае, если записей больше одной %).
Что, впрочем, в данном случае могло бы быть защитой от вмешательства в отношение ```glob```. Ну ладно.
19.05.2020 00:May
XRevan86 post_id=827 time=1589846974 user_id=76 Написал:В иной СУБД иначе могла бы быть ошибка в случае, если записей больше одной
[Потыкав тесты…] А в Sqlite3 в этой конструкции оно возьмёт первую запись без ошибок.
XRevan86 post_id=827 time=1589846974 user_id=76 Написал:Что, впрочем, в данном случае могло бы быть защитой от вмешательства в отношение glob.
Не могло, если была добавлена запись с `PRIMARY KEY` меньше, о чём я уже писал:
```sql
INSERT INTO glob (rowid, id, gid) VALUES (-100500, -100500, -1);
```
• Правила форума
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
• [Новичкам] Как правильно задавать вопросы, чтобы Вам помогли
«Буду бить аккуратно, но сильно!» © Лёлик, х/ф «Бриллиантовая рука»
Пользователи, просматривающие эту тему: 1 Гость(ей)