Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Сортировка с участием PK / 15 сообщений из 15, страница 1 из 1
29.10.2015, 16:37
    #39090297
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Добрый день!
Есть такая таблица:
Код: sql
1.
2.
3.
4.
5.
6.
create table T(A_ID integer not null,
 B_ID integer not null,
 C_ID integer not null,
 S_DATE date not null,
 F_DATE date not null);
alter table T add constraint PK_T primary key (A_ID, B_ID, C_ID);

A_ID и B_ID - внешние ключи, C_ID заполняется автоинкрементом для каждой комбинации A_ID/B_ID. Периодически некоторые строки приходится удалять. Нужно после внесенных изменений в таблицу переназначить C_ID последовательно для всех строк c A_ID/B_ID, отсортировав предварительно список по S_DATE, F_DATE, OLD.C_ID.
Вопрос: как это проще сделать? Если бы C_ID не входило в PK - проблемы бы не было, а тут - PK, т.е. получается, только сортировка методом пузырька?
...
Рейтинг: 0 / 0
29.10.2015, 16:41
    #39090302
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Hello, Kirill Razuvaev!
You wrote on 29 октября 2015 г. 16:40:38:

Kirill Razuvaev> Вопрос: как это проще сделать?Вопрос: науха это вообще делать?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
29.10.2015, 16:45
    #39090311
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Kirill Razuvaev,

что за бред? Если у тебя есть поле автоинкремента, то почему оно не PK?
Не надо модифицировать ПК. Это вообще идиотизм, особенно если потом на этот ПК ссылаться другие таблицы будут.
...
Рейтинг: 0 / 0
29.10.2015, 17:22
    #39090355
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Симонов Денисчто за бред? Если у тебя есть поле автоинкремента, то почему оно не PK?
Не надо модифицировать ПК. Это вообще идиотизм, особенно если потом на этот ПК ссылаться другие таблицы будут.Там не полный автоинкремент. Автоинкремент организуется не для всей таблицы, а только для всех строк с одинаковой парой значений A_ID/B_ID.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
| A_ID | B_ID | C_ID |  S_DATE  |  F_DATE  |
|  33  |   12 |  1   | 15.04.10 | 16.04.10 |
|  33  |   17 |  1   | 10.11.12 | 15.11.12 |
|  33  |   17 |  2   | 10.11.12 | 17.11.12 |
|  33  |   17 |  3   | 10.11.12 | 14.11.12 |
|  33  |   17 |  4   | 10.11.12 | 31.12.12 |
|  33  |   95 |  1   | 01.01.14 | 31.01.14 |
|  33  |   95 |  2   | 01.01.14 | 31.01.14 |
К примеру, удаляется запись с сочетанием "33-17-2", после этого нужно удалить образовавшуюся дырку и "поменять местами" записи с C_ID 1 и 3
Код: plaintext
1.
2.
3.
| A_ID | B_ID | C_ID |  S_DATE  |  F_DATE  |
|  33  |   17 |  1   | 10.11.12 | 14.11.12 |
|  33  |   17 |  2   | 10.11.12 | 15.11.12 |
|  33  |   17 |  3   | 10.11.12 | 31.12.12 |
В PK в дальнейшем связка нигде не участвует, просто заказчик хочет чтобы визуально все было пронумеровано правильно и "без дырок".
...
Рейтинг: 0 / 0
29.10.2015, 17:28
    #39090366
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Hello, Kirill Razuvaev!
You wrote on 29 октября 2015 г. 17:27:59:

Kirill Razuvaev> заказчик хочет чтобы визуально все было пронумеровано правильно и "без дырок"
рисуй нумерацию на клиенте.
ключи это ключи.
не нужно их использовать для "нумерации".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
29.10.2015, 17:31
    #39090367
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
МимопроходящийHello, Kirill Razuvaev!
You wrote on 29 октября 2015 г. 17:27:59:

Kirill Razuvaev> заказчик хочет чтобы визуально все было пронумеровано правильно и "без дырок"
рисуй нумерацию на клиенте.
ключи это ключи.
не нужно их использовать для "нумерации".Оно уже, увы, так нарисовано... :-(
...
Рейтинг: 0 / 0
29.10.2015, 17:35
    #39090374
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Kirill Razuvaev,

так не хрен тогда порядок хранить. Как уже сказали сортируешь запросом и нумеруешь на клиенте.

И кстати причём тут пузырёк?
...
Рейтинг: 0 / 0
29.10.2015, 17:35
    #39090376
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Hello, Kirill Razuvaev!
You wrote on 29 октября 2015 г. 17:35:44:

Kirill Razuvaev> Оно уже, увы, так нарисовано...
закрасить грунтовкой и нарисовать заново.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
29.10.2015, 17:37
    #39090378
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Kirill RazuvaevАвтоинкремент организуется не для всей таблицы, а только для всех строк с одинаковой парой значений A_ID/B_ID.
хотелось бы услышать, как это достигается в многопользовательском режиме.

Kirill Razuvaevзаказчик хочет чтобы визуально все было пронумеровано правильно и "без дырок".
это возможно только в монопольном режиме. Вообще, заказчик часто хочет много чего, о чем не имеет ни малейшего представления.
...
Рейтинг: 0 / 0
29.10.2015, 18:28
    #39090439
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Kirill Razuvaev> Оно уже, увы, так нарисовано... :-(

Дык перерисуй. Ты ж разработчик или не твоя вотчина?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
30.10.2015, 04:04
    #39090677
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Kirill Razuvaev,

Просто не трогай C_ID, убери его из ПК, а на клиенте рисуй что хочешь. Будет просто лишнее поле.
...
Рейтинг: 0 / 0
30.10.2015, 10:18
    #39090813
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
kdvKirill RazuvaevАвтоинкремент организуется не для всей таблицы, а только для всех строк с одинаковой парой значений A_ID/B_ID.
хотелось бы услышать, как это достигается в многопользовательском режиме.
Kirill Razuvaevзаказчик хочет чтобы визуально все было пронумеровано правильно и "без дырок".
это возможно только в монопольном режиме. Вообще, заказчик часто хочет много чего, о чем не имеет ни малейшего представления.Бизнес-специфика объекта в том, что правки редки, и корректировки вносятся в режиме select with lock родительского объекта.
Гаджимурадов РустамKirill Razuvaev> Оно уже, увы, так нарисовано... :-(
Дык перерисуй. Ты ж разработчик или не твоя вотчина?Надо посмотреть внимательно, что там дальше в структуре, может, действительно, проще туда сделать суррогатный PK с автоинкрементом, а A_ID/B_ID оставить просто FK, нумерацию при этом формировать динамически.
...
Рейтинг: 0 / 0
30.10.2015, 11:00
    #39090848
DBConstructor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
Kirill RazuvaevВ PK в дальнейшем связка нигде не участвует, просто заказчик хочет чтобы визуально все было пронумеровано правильно и "без дырок".
Как говориться - "The customer is a king". Понимаю...
Как один из вариантов, могу предложить сделать обновляемое на триггерах представление с тем же именем, которое клиент будет воспринимать как таблицу. Что-то типа:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
CREATE TABLE T_
(
    A_ID INTEGER NOT NULL,
    B_ID INTEGER NOT NULL,
    C_ID INTEGER NOT NULL,
    S_DATE DATE NOT NULL,
    F_DATE DATE NOT NULL,
  CONSTRAINT T___PK PRIMARY KEY (A_ID, B_ID, C_ID)
  CONSTRAINT T___FK__GUIDE FOREIGN KEY (A_ID, B_ID)
    REFERENCES GUIDE (A_ID, B_ID) -- обязательно с запретом каскадного изменения
                                  -- иначе возможно рассогласование C_ID
                                  -- относительно (A_ID, B_ID)
);
COMMIT WORK;


CREATE OR ALTER VIEW T
AS
SELECT A_ID, B_ID, C_ID, S_DATE, F_DATE
  FROM T_;
COMMIT WORK;


SET TERM ^;
CREATE OR ALTER TRIGGER TR__T_BIUD
  FOR "T"
  ACTIVE
  BEFORE INSERT OR UPDATE OR DELETE
  POSITION 0
AS
  DECLARE VARIABLE NEW_C_ID INTEGER DEFAULT NULL;
  DECLARE VARIABLE OLD_C_ID INTEGER DEFAULT NULL;
BEGIN
  IF (INSERTING) THEN
    BEGIN
      -- IF (NEW.A_ID IS NULL OR NEW.B_ID IS NULL) THEN
      --   EXCEPTION <какое-то исключение>
      SELECT NULL
        FROM T_
        WHERE A_ID = NEW.A_ID
          AND B_ID = NEW.B_ID
        FOR UPDATE WITH LOCK
        INTO: NEW_C_ID;
      SELECT Max(C_ID)
        FROM T_
        WHERE A_ID = NEW.A_ID
          AND B_ID = NEW.B_ID
        INTO: NEW_C_ID;
      NEW.C_ID = Coalesce(NEW_C_ID, 0) + 1;
      INSERT INTO T_ (A_ID, B_ID, C_ID, S_DATE, F_DATE)
        VALUES (NEW.A_ID, NEW.B_ID, NEW.C_ID, NEW.S_DATE, NEW.F_DATE);
    END
  ELSE IF (DELETING) THEN
    BEGIN
      SELECT NULL
        FROM T_
        WHERE A_ID = NEW.A_ID
          AND B_ID = NEW.B_ID
          AND C_ID >= OLD.C_ID
        FOR UPDATE WITH LOCK
        INTO: NEW_C_ID;
      NEW_C_ID = OLD.C_ID;
      DELETE
        FROM T_
        WHERE A_ID = OLD.A_ID
          AND B_ID = OLD.B_ID
          AND C_ID = OLD.C_ID;
      FOR
          SELECT C_ID
            FROM T_
            WHERE A_ID = OLD.A_ID
              AND B_ID = OLD.B_ID
              AND C_ID > OLD.C_ID
            ORDER BY C_ID
            INTO: OLD_C_ID
        DO
          BEGIN
            UPDATE T_
              SET C_ID = :NEW_C_ID
              WHERE A_ID = OLD.A_ID
                AND B_ID = OLD.B_ID
                AND C_ID = :OLD_C_ID;
            NEW_C_ID = NEW_C_ID + 1;
          END
    END
  ELSE
    UPDATE T_
      SET
        A_ID   = NEW.A_ID,
        B_ID   = NEW.B_ID,
        C_ID   = NEW.C_ID,
        S_DATE = NEW.S_DATE,
        F_DATE = NEW.F_DATE
      WHERE A_ID = OLD.A_ID
        AND B_ID = OLD.B_ID
        AND C_ID = OLD.C_ID;
END^
SET TERM ;^
COMMIT WORK;



Возможно, я мог что-то упустить из виду, так что ревизия и тестирования триггера лишними не будут.
...
Рейтинг: 0 / 0
30.10.2015, 11:04
    #39090853
DBConstructor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
сразу нашел за собой ошибку. Там где DELETING, исправьте фрагмент блокировки записей на:
Код: sql
1.
2.
3.
4.
5.
6.
7.
      SELECT NULL
        FROM T_
        WHERE A_ID = OLD.A_ID
          AND B_ID = OLD.B_ID
          AND C_ID >= OLD.C_ID
        FOR UPDATE WITH LOCK
        INTO: NEW_C_ID;
...
Рейтинг: 0 / 0
30.10.2015, 11:16
    #39090869
DBConstructor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с участием PK
и еще, в DELETING, DELETE и FOR надо заключить в:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
      IF (EXISTS (
            SELECT 0
              FROM T_
              WHERE A_ID = OLD.A_ID
                AND B_ID = OLD.B_ID
                AND C_ID = OLD.C_ID)) THEN
        BEGIN
          .
          .
          .
        END    
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Сортировка с участием PK / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]