Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Привет всем!
Имею ХП, которая осуществляет вставку строк в таблицу T1 в курсоре.
т.е. курсором пробегаю по некой таблице T2, считываю значение поля и потом если это значение есть в T1, то делать UPDATE, если нет - тогда INSERT.
Так вот T1 имеет identity-поле и после вставки id первой записи = кол-ву строк в T2, а не с 1.
хотя перед этим сделал dbcc checkident(T1,reseed,0)
транзакций при вставке/обновлении не использую.
Если непонятно, то выложу код.
12 мар 14, 02:37    [15707964]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Замглавврача
Member [заблокирован]

Откуда: Психиатрическая клиника имени Джуджа
Сообщений: 4017
выложи код
12 мар 14, 05:18    [15708020]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Добрый Э - Эх
Guest
RAMZEZ II,

может посмотреть в сторону MERGE. Оно как раз для реализации логики UPSERT-а придумывалось: вставляет новое, апдейтит существующее (ещё может удалять ненужное)...
12 мар 14, 05:28    [15708026]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Добрый Э - Эх,

ок. гляну
12 мар 14, 07:46    [15708097]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Замглавврача,

В T2 есть автоинкрементный столбец ID.

+
DECLARE Cur1 CURSOR FOR SELECT s1, n1 FROM T2
    OPEN Cur1
    WHILE 1=1 BEGIN 
     FETCH NEXT FROM Cur1 INTO @s, @n
      IF @@FETCH_STATUS != 0 BREAK 
       IF EXISTS(SELECT * FROM T1 WHERE n = @n)
	    UPDATE T1 SET s = @s WHERE n = @n
	   ELSE
  	    INSERT INTO T2(s, n) VALUES(@s, @n)  		 
    END
    CLOSE Cur1
    DEALLOCATE Cur1


В итоге, если в Т2 6 строк, то в Т1 появятся строки, начиная с 6.
12 мар 14, 07:58    [15708110]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
RAMZEZ II,

ошибся!!!! не в T2 автоинкрементный столбец, а в Т1
12 мар 14, 07:59    [15708112]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Добрый Э - Эх
RAMZEZ II,

может посмотреть в сторону MERGE. Оно как раз для реализации логики UPSERT-а придумывалось: вставляет новое, апдейтит существующее (ещё может удалять ненужное)...


MERGE классная штука, все просто, но при вставке все равно инкрементное поле кривое, аналогично как и в курсоре :(
12 мар 14, 08:55    [15708186]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Ну, тогда код показывайте.
12 мар 14, 08:57    [15708189]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
tpg,
код есть выше в спойлере, но там реализовано через курсор, с MERGE такой же результат
12 мар 14, 09:04    [15708209]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
RAMZEZ II
Добрый Э - Эх
RAMZEZ II,

может посмотреть в сторону MERGE. Оно как раз для реализации логики UPSERT-а придумывалось: вставляет новое, апдейтит существующее (ещё может удалять ненужное)...


MERGE классная штука, все просто, но при вставке все равно инкрементное поле кривое, аналогично как и в курсоре :(
триггер INSTEAD OF INSERT ?

и еще плюсом к коду покажите результат SELECT @@VERSION
12 мар 14, 09:05    [15708214]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
RAMZEZ II
tpg,
код есть выше в спойлере, но там реализовано через курсор, с MERGE такой же результат
приведите код, который полностью воспроизводит ошибку, чтобы можно было нажать F5 и увидеть неправильный результат. В вашем приведенном отрывке вообще бесконечный цикл.
12 мар 14, 09:08    [15708218]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
RAMZEZ II
Так вот T1 имеет identity-поле и после вставки id первой записи = кол-ву строк в T2, а не с 1.
хотя перед этим сделал dbcc checkident(T1,reseed,0)
Если непонятно, то выложу код.


пока, что похоже на враньё...ниже ваш же код:

declare @t2 table ( s1 int, n1 int )
insert into @t2
values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

declare @t1 table ( id int identity, s int, n int )

declare @s int, @n int
DECLARE Cur1 CURSOR FOR SELECT s1, n1 FROM @t2
    OPEN Cur1
    WHILE 1=1 BEGIN 
     FETCH NEXT FROM Cur1 INTO @s, @n
      IF @@FETCH_STATUS != 0 BREAK 
       IF EXISTS(SELECT * FROM @t1 WHERE n = @n)
	    UPDATE @t1 SET s = @s WHERE n = @n
	   ELSE
  	    INSERT INTO @t1(s, n) VALUES(@s, @n)  		 
    END
    CLOSE Cur1
    DEALLOCATE Cur1

select * from @t1
12 мар 14, 09:13    [15708231]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Guf
Member

Откуда: Новосибирск
Сообщений: 659
RAMZEZ II
tpg,
код есть выше в спойлере, но там реализовано через курсор, с MERGE такой же результат


RAMZEZ II
DECLARE Cur1 CURSOR FOR SELECT s1, n1 FROM T2
    OPEN Cur1
    WHILE 1=1 BEGIN 
     FETCH NEXT FROM Cur1 INTO @s, @n
      IF @@FETCH_STATUS != 0 BREAK 
       IF EXISTS(SELECT * FROM T1 WHERE n = @n)
	    UPDATE T1 SET s = @s WHERE n = @n
	   ELSE
  	    INSERT INTO T2(s, n) VALUES(@s, @n)  		 
    END
    CLOSE Cur1
    DEALLOCATE Cur1


Поэтому давайте полный код, который можно воспроизвести, включая создание таблиц, наполнение их данными и потом уже MERGE\CURSOR.
И не по-памяти, копи-паст.
12 мар 14, 09:22    [15708247]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Ruuu
RAMZEZ II
пропущено...


MERGE классная штука, все просто, но при вставке все равно инкрементное поле кривое, аналогично как и в курсоре :(
триггер INSTEAD OF INSERT ?

и еще плюсом к коду покажите результат SELECT @@VERSION


Версия: Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64) Jul 9 2008 14:17:44 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7600: )
12 мар 14, 09:29    [15708259]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Guf
RAMZEZ II
tpg,
код есть выше в спойлере, но там реализовано через курсор, с MERGE такой же результат


RAMZEZ II
DECLARE Cur1 CURSOR FOR SELECT s1, n1 FROM T2
    OPEN Cur1
    WHILE 1=1 BEGIN 
     FETCH NEXT FROM Cur1 INTO @s, @n
      IF @@FETCH_STATUS != 0 BREAK 
       IF EXISTS(SELECT * FROM T1 WHERE n = @n)
	    UPDATE T1 SET s = @s WHERE n = @n
	   ELSE
  	    INSERT INTO T2(s, n) VALUES(@s, @n)  		 
    END
    CLOSE Cur1
    DEALLOCATE Cur1


Поэтому давайте полный код, который можно воспроизвести, включая создание таблиц, наполнение их данными и потом уже MERGE\CURSOR.
И не по-памяти, копи-паст.


Код рабочий, просто вместо Т2, нужно Т1 (где пометил красным цветом)
12 мар 14, 09:30    [15708262]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Knyazev Alexey
RAMZEZ II
Так вот T1 имеет identity-поле и после вставки id первой записи = кол-ву строк в T2, а не с 1.
хотя перед этим сделал dbcc checkident(T1,reseed,0)
Если непонятно, то выложу код.


пока, что похоже на враньё...ниже ваш же код:

declare @t2 table ( s1 int, n1 int )
insert into @t2
values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

declare @t1 table ( id int identity, s int, n int )

declare @s int, @n int
DECLARE Cur1 CURSOR FOR SELECT s1, n1 FROM @t2
    OPEN Cur1
    WHILE 1=1 BEGIN 
     FETCH NEXT FROM Cur1 INTO @s, @n
      IF @@FETCH_STATUS != 0 BREAK 
       IF EXISTS(SELECT * FROM @t1 WHERE n = @n)
	    UPDATE @t1 SET s = @s WHERE n = @n
	   ELSE
  	    INSERT INTO @t1(s, n) VALUES(@s, @n)  		 
    END
    CLOSE Cur1
    DEALLOCATE Cur1

select * from @t1

Врать не собирался и не собираюсь, но действительно Ваш код работает правильно, мой же аналогичный - не фига.
12 мар 14, 09:34    [15708273]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
RAMZEZ II
мой же аналогичный - не фига.

чудес не бывает...смотрите триггеры на объектах...выкладывайте РЕПО сюда, чтобы мы могли повторить ваш случай
12 мар 14, 09:36    [15708283]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Knyazev Alexey,
триггеров на T1 нету.
12 мар 14, 09:41    [15708297]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
RAMZEZ II
Версия: Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64) Jul 9 2008 14:17:44 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7600: )
Поставьте сервис паки, их уже было аж три штуки на 2008-й. Хотя вряд ли ошибка из-за них, но есть шанс, что таки да. Плюс это убережет вас от многих других неприятностей.
12 мар 14, 09:42    [15708304]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Ребят, извиняюсь, ошибся и запутал наверно вас.
Проблема есть, но после вставки в таблицу identity-поле начинает свое значение с N, где N = кол-во строк в T2+1, т.е. как будто вставка уже прошла, потом прошло удаление и снова уже произошла вставка значений уже с фиксацией их в БД
12 мар 14, 10:12    [15708385]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
RAMZEZ II
Ребят, извиняюсь, ошибся и запутал наверно вас.


где код? вас уже несколько раз об этом попросили...!
12 мар 14, 10:17    [15708403]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
invm
Member

Откуда: Москва
Сообщений: 9719
Что вернет ident_current('T1') до выполнения вашего кода?
12 мар 14, 10:18    [15708406]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Knyazev Alexey,

может дело в заполнении из linked-сервера:
SELECT @idTB = idTB FROM dbo.tbanktb(nolock) WHERE sKod = @Kod   
	
   --Step 1.-----------------------------------
    CREATE TABLE #tmp_1(sOSB varchar(255) NULL, 
	                    nOSB varchar(10) NULL)
    SELECT @s = 'INSERT INTO #tmp_1 SELECT * FROM OPENQUERY ("'+@srv+'",''SELECT BankName, nOSB FROM [dbo].[t_sprBank]'')'          
    EXEC(@s)
	 
	/*MERGE dbo.tBank AS target 
	USING (SELECT sOSB, nOSB FROM #tmp_1) AS source (sOSB, nOSB)
	ON (target.nOSB = source.nOSB AND target.idTB = @idTB)
	WHEN MATCHED THEN
	 UPDATE SET sName = source.sOSB
	 WHEN NOT MATCHED THEN
	  INSERT (sName, idTB, nOSB) VALUES(source.sOSB, @idTB, source.nOSB);*/
    DECLARE Cur1 CURSOR FOR SELECT sOSB, nOSB FROM #tmp_1
    OPEN Cur1
    WHILE 1=1 BEGIN 
     FETCH NEXT FROM Cur1 INTO @NameOSB, @OSB
      IF @@FETCH_STATUS != 0 BREAK 
       IF EXISTS(SELECT * FROM dbo.tbank(nolock) WHERE nOSB = @OSB AND idTB = @idTB)
	    UPDATE dbo.tbank SET sName = @NameOSB WHERE nOSB = @OSB AND 
		                                            idTB = @idTB
	   ELSE
  	    INSERT INTO dbo.tbank(sName, idTB, nOSB) VALUES(@NameOSB, @idTB, @OSB)  		 
    END
    CLOSE Cur1
    DEALLOCATE Cur1
12 мар 14, 10:35    [15708478]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
invm
Что вернет ident_current('T1') до выполнения вашего кода?


= 0
12 мар 14, 10:38    [15708490]     Ответить | Цитировать Сообщить модератору
 Re: Вставка инкрементных значений работает неправильно  [new]
RAMZEZ II
Member

Откуда: Приморье
Сообщений: 535
Выложил код и ваши мысли, господа???
13 мар 14, 03:02    [15714642]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить