2017-01-17 2 views
0

У меня есть таблица с 4 столбцами ID, c1, c2 и LOT. Идентификатор - это первичный ключ. Для каждой записи, когда c1 равно 5, я хочу автоматически генерировать число для LOT, которое будет последовательностью, начинающейся с 1 для каждого отдельного значения c2.MSSQL Может ли автокопирование столбца при определенных обстоятельствах

Так что если c1 не 5, LOT остается null. Но если c1 является 5, то для каждой записи где c2 = 1 Я хочу, чтобы заполнить LOT с автоинкрементной последовательностью, начиная с 1. Ex:

ID c1 c2 LOT 
1 3 
2 5 1 1 
3 5 1 2 
4 5 1 3 
5 4 

Затем сделать то же самое для другого значения с2. Так что если с2 2, есть еще куча автоинкрементные чисел LOT, начиная с 1:

ID c1 c2 LOT 
6 3 
7 5 2 1 
8 5 1 4 
9 5 2 2 
10 5 2 3 

Мы используем MSSQL 2014 Enterprise Ed. Было бы полезно использовать разбиение таблиц или мне нужно создавать специальные таблицы для каждого отдельного значения C2?

+0

Извините, я не вижу ссылки на триггеры в этой ссылке. – user1693404

+1

Извините, что я отправил неправильную ссылку ранее. См. Http://stackoverflow.com/q/24335341/1072229 для аналогичного обсуждения. –

+0

Спасибо. Это выглядит актуальным. Я также нашел это: http://stackoverflow.com/questions/2205036/sql-server-unique-auto-increment-column-in-the-context-of-another-column?rq=1 с боковой панели, которая также адресует это с помощью триггера, который объясняет мою озабоченность ниже (о уникальности) – user1693404

ответ

0

Спасибо всем за предложения использовать триггер (все проголосовали). Оказывается (как я уже упоминал в комментарии выше), статья, появившаяся на боковой панели (SQL Server unique auto-increment column in the context of another column), показывает подробную конструкцию правильного триггера INSTEAD OF INSERT. Автор упоминает, что он «не проверен», и действительно есть небольшая ошибка (отсутствующая GROUP BY ParentEntityID в предложении WITH), но любой, кто копирует код, получит ошибку, которая очевидна для исправления. Наверное, не кошерно исправлять этот пост здесь, но другой вопрос - 6 лет.

1

не с полем идентификации, вы можете использовать триггер вместо этого.

1

Нет способа сделать это, используя функцию Identity, однако рассмотрите возможность использования Instead of trigger для ручного управления такими значениями, как вы хотите.

+0

Я думаю, я не вижу, как триггеры могут быть гарантированы для создания уникальных непрерывных последовательностей. Как вы решаете проблему с несколькими одновременными вставками? – user1693404

+0

Я не знаю, как бы вы столкнулись с проблемой одновременных вставок, но я не думаю, что действительно существует какой-либо способ гарантировать это, не используя идентификатор двигателя. –

+0

Собственно, в сообщении, которое я упоминаю в «моем собственном», ниже, код запуска использует SET DESACTION ISOLATION LEVEL SERIALIZABLE, который, по словам автора, гарантирует непрерывную уникальную последовательность (но с некоторыми потенциальными проблемами производительности). – user1693404

0

Вы можете использовать логику для генерации LOT в запросе или представлении:

SELECT ID, C1, C2, 
    CASE 
     WHEN C1<>5 OR C2 IS NULL THEN NULL 
     ELSE COUNT(*) OVER (PARTITION BY C1, C2 ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
    END AS LOT 
FROM D 
ORDER BY ID 

Учитывая таблица генерируется с (ID, C1, C2):

CREATE TABLE D (ID INT PRIMARY KEY IDENTITY, C1 INT, C2 INT) 
INSERT D VALUES (3,NULL), 
       (5,1), 
       (5,1), 
       (5,1), 
       (4,NULL), 
       (3,NULL), 
       (5,2), 
       (5,1), 
       (5,2), 
       (5,2) 

Запрос производит вывод было указано выше:

ID C1 C2 LOT 
1 3 
2 5 1 1 
3 5 1 2 
4 5 1 3 
5 4 
6 3 
7 5 2 1 
8 5 1 4 
9 5 2 2 
10 5 2 3 

оператор используется для создания LOT, COUNT(*) OVER (PARTITION BY C1, C2 ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, просто подсчитывает количество строк до и включает текущую строку, где C1 и C2 равны текущей строке. Например, для строки 4 кортеж (c1, c2) = (5,1) наблюдается в 3 записях до и включая эту строку (строки 2, 3 и 4), поэтому LOT = 3.

Смежные вопросы