powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Сортировка с участием PK
15 сообщений из 15, страница 1 из 1
Сортировка с участием PK
    #39090297
Kirill Razuvaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!
Есть такая таблица:
Код: 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
Сортировка с участием PK
    #39090302
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hello, Kirill Razuvaev!
You wrote on 29 октября 2015 г. 16:40:38:

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

что за бред? Если у тебя есть поле автоинкремента, то почему оно не PK?
Не надо модифицировать ПК. Это вообще идиотизм, особенно если потом на этот ПК ссылаться другие таблицы будут.
...
Рейтинг: 0 / 0
Сортировка с участием PK
    #39090355
Kirill Razuvaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисчто за бред? Если у тебя есть поле автоинкремента, то почему оно не 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
Сортировка с участием PK
    #39090366
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hello, Kirill Razuvaev!
You wrote on 29 октября 2015 г. 17:27:59:

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

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

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

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

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

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

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

Просто не трогай C_ID, убери его из ПК, а на клиенте рисуй что хочешь. Будет просто лишнее поле.
...
Рейтинг: 0 / 0
Сортировка с участием PK
    #39090813
Kirill Razuvaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvKirill RazuvaevАвтоинкремент организуется не для всей таблицы, а только для всех строк с одинаковой парой значений A_ID/B_ID.
хотелось бы услышать, как это достигается в многопользовательском режиме.
Kirill Razuvaevзаказчик хочет чтобы визуально все было пронумеровано правильно и "без дырок".
это возможно только в монопольном режиме. Вообще, заказчик часто хочет много чего, о чем не имеет ни малейшего представления.Бизнес-специфика объекта в том, что правки редки, и корректировки вносятся в режиме select with lock родительского объекта.
Гаджимурадов РустамKirill Razuvaev> Оно уже, увы, так нарисовано... :-(
Дык перерисуй. Ты ж разработчик или не твоя вотчина?Надо посмотреть внимательно, что там дальше в структуре, может, действительно, проще туда сделать суррогатный PK с автоинкрементом, а A_ID/B_ID оставить просто FK, нумерацию при этом формировать динамически.
...
Рейтинг: 0 / 0
Сортировка с участием PK
    #39090848
DBConstructor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Сортировка с участием PK
    #39090853
DBConstructor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сразу нашел за собой ошибку. Там где 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
Сортировка с участием PK
    #39090869
DBConstructor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и еще, в 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
15 сообщений из 15, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Сортировка с участием PK
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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