Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
vrtlpilot Member Откуда: Сообщений: 29 |
Суть вопроса. Есть таблица Tbl_A. Следующей структуры: TABLE [dbo].[Tbl_A]( [IDTbl_A] [int] IDENTITY(1,1) NOT NULL, [KodProdukt] [int] NOT NULL, [KodIB] [int] NOT NULL, [KodSort] [int] NOT NULL CONSTRAINT [DF_Tbl_A_KodSort] DEFAULT ((999)) ) ON [PRIMARY] Необходимо в нее вставить данные, но так что бы у всех последующих элементов, KodSort инкрементировался (до первого пробела. внутри KodProdukt) например есть набор:
При вставке SET @KodProdukt = 230 SET @KodIB = 254 SET @KOdSort = 41 Должно получиться так:
Так вот собственно, я смог придумать только связку курсор+временная таблица. Но меня этот метод сильно расстраивает. Может кто-то предложит более оптимальное решение? DECLARE @KodProdukt int, @KodIB int, @KodSort int, @tKodSort int SET @KodProdukt = 230 SET @KodIB = 254 SET @KOdSort = 41 SET @tKodSort = @KodSort ----------------- IF EXISTS (SELECT [KodProdukt], [KodIB] FROM [dbo].[Tbl_A] WHERE [KodProdukt] = @KodProdukt AND [KodIB] = @KodIB) BEGIN UPDATE [dbo].[Tbl_A] SET [KodSort] = @KodSort WHERE KOdProdukt = @KodProdukt and KodIB = @KodIB END ELSE BEGIN INSERT INTO [dbo].[Tbl_A] ([KodProdukt], [KodIB], [KodSort]) VALUES (@KodProdukt, @KodIB, @KodSort) END ----------------- DECLARE @CurIDTbl_A int, @CurKodSort int, @CntRec int if OBJECT_ID('tempdb..##Tmp_IDTbl_A')>0 exec('drop table ##Tmp_IDTbl_A') CREATE TABLE ##Tmp_IDTbl_A (IDTbl_A int) DECLARE #Tmp_Tbl_A CURSOR FOR SELECT IDTbl_A FROM Tbl_A WHERE (KodProdukt = @KodProdukt) AND (KodSort >= @KodSort) AND (KodSort < 10000) ORDER BY KodSort OPEN #Tmp_Tbl_A FETCH NEXT FROM #Tmp_Tbl_A INTO @CurIDTbl_A WHILE (@@FETCH_STATUS=0) AND (@tKodSort > 0) BEGIN SELECT @CntRec = COUNT(*) FROM Tbl_A WHERE (KodProdukt = @KodProdukt) and (KodSort = @tKodSort) IF @CntRec >= 1 BEGIN INSERT INTO ##Tmp_IDTbl_A (IDTbl_A) Values(@CurIDTbl_A) SET @tKodSort = @tKodSort + 1 END ELSE SET @tKodSort = 0 FETCH NEXT FROM #Tmp_Tbl_A INTO @CurIDTbl_A END DEALLOCATE #Tmp_Tbl_A UPDATE Tbl_A SET KodSort = KodSort + 1 where IDTbl_A in (Select IDTbl_A FROM ##Tmp_IDTbl_A) if OBJECT_ID('tempdb..##Tmp_IDTbl_A')>0 exec('drop table ##Tmp_IDTbl_A') |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
1 июл 14, 09:29 [16241785] Ответить | Цитировать Сообщить модератору |
Guf Member Откуда: Новосибирск Сообщений: 658 |
vrtlpilot, Если я все правильно напутал, то UPDATE [a] SET [KodSort] = [a].[KodSort] + 1 FROM [dbo].[Tbl_A] [a] WHERE [a].[KodProdukt] = @KodProdukt AND [a].[KodSort] >= @KOdSort ; А потом уже инсерт |
1 июл 14, 10:57 [16242261] Ответить | Цитировать Сообщить модератору |
vrtlpilot Member Откуда: Сообщений: 29 |
Я тоже так подумал, но нельзя допускать дублирования KodSort внутри группы. |
||
1 июл 14, 11:27 [16242462] Ответить | Цитировать Сообщить модератору |
Guf Member Откуда: Новосибирск Сообщений: 658 |
vrtlpilot, А где дублирование, если Вы сначала сдвинете пололовину кодов сортировки, а потом в образовавшуюся дырку вставите новый? Дырки допускаются? P.S. про транзакции и все такое, надеюсь, не надо объяснять? |
1 июл 14, 11:33 [16242506] Ответить | Цитировать Сообщить модератору |
vrtlpilot Member Откуда: Сообщений: 29 |
Верно. Сдвинутся все коды, а мне нужно до первой дырки. (как в примере)
И, да, дырки допускаются. |
||||
1 июл 14, 12:12 [16242816] Ответить | Цитировать Сообщить модератору |
Minamoto Member Откуда: Москва Сообщений: 1162 |
Ну добавьте туда INNER JOIN [dbo].[Tbl_A] [b] on [a].[KodProdukt] = [b].[KodProdukt] AND [a].[KodSort] + 1 = [b].[KodSort] и в where >= замените на [a].[KodProdukt] + 1 = @KOdSort, чтобы ближнюю дырку исключить. |
||
1 июл 14, 12:19 [16242873] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
UPDATE [a] SET [KodSort] = [a].[KodSort] + 1 FROM [dbo].[Tbl_A] [a] WHERE [a].[KodProdukt] = @KodProdukt AND [a].[KodSort] >= @KOdSort and exists(select 1 from [dbo].[Tbl_A] where [KodProdukt] = [a].[KodProdukt] and [KodSort] = [a].[KodSort] + 1) ; |
||
1 июл 14, 12:20 [16242885] Ответить | Цитировать Сообщить модератору |
Guf Member Откуда: Новосибирск Сообщений: 658 |
Тогда можно воспользоваться поиском и выбрать любой вариант на свой вкус. Тогда в условии апдейта добавится еще одно условие, код сортировки должен быть меньше первой дырки. |
||
1 июл 14, 12:21 [16242892] Ответить | Цитировать Сообщить модератору |
vrtlpilot Member Откуда: Сообщений: 29 |
Выставляю на критику публики то, что родило мое воспаленное сознание спустя восемь часов "творческих" мук.DECLARE @KodProdukt int, @KodIB int, @KodSort int, @MinKodSort int, @MaxKodSort int SET @KodProdukt = 18 SET @KodIB = 254 SET @KOdSort = 10000 SET @MinKodSort = 10000 SET @MaxKodSort = 0 DELETE FROM [Tbl_A] WHERE KodProdukt = @KodProdukt AND KodIB=@KodIB Select @MinKodSort=Min(KodSort) From Tbl_A Where (KodSort>=@KodSort) And (KodProdukt=@KodProdukt) IF (@MinKodSort = @KodSort) and (@KodSort < 10000) BEGIN SELECT @MaxKodSort = Min(s1.KodSort+1) FROM [Tbl_A] as s1 WHERE (s1.KodSort+1 NOT IN (SELECT s2.KodSort FROM [Tbl_A] AS [s2] Where s2.KodProdukt = @KodProdukt)) AND s1.KodProdukt=@KodProdukt AND s1.KodSort < 10000 AND s1.KodSort>=@MinKodSort UPDATE [Tbl_A] SET [KodSort] = [KodSort] + 1 WHERE [KodProdukt] = @KodProdukt AND [KodSort] BETWEEN @MinKodSort AND @MaxKodSort END IF EXISTS (SELECT [KodProdukt], [KodIB] FROM [dbo].[Tbl_A] WHERE [KodProdukt] = @KodProdukt AND [KodIB] = @KodIB) BEGIN UPDATE [dbo].[Tbl_A] SET [KodSort] = @KodSort WHERE KodProdukt = @KodProdukt and KodIB = @KodIB END ELSE BEGIN INSERT INTO [dbo].[Tbl_A] ([KodProdukt], [KodIB], [KodSort]) VALUES (@KodProdukt, @KodIB, @KodSort) END |
1 июл 14, 18:25 [16245415] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |