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

Откуда:
Сообщений: 71
Всем привет. Пишу хранимую процедуру в MS SQL SERVER 2005 для импорта данных из одной таблицы в другую. Требуется исключить дублирующие строки. Столкнулся со следующей проблемой. Код:

DECLARE cur_my_el CURSOR FOR SELECT
OS_NAME, WK_NAME, POSTQUAL
from IMPORT_NR_ELECTR

declare @kol int
select @kol = count (*) from IMPORT_NR_ELECTR

declare @var_os_name char(45), @var_wk_name char(45), @var_postqual char(30)
declare @i int

OPEN cur_my_el
set @i = 0

WHILE @i < @kol /*----цикл-----------*/
BEGIN

select @i = @i + 1
FETCH next FROM cur_my_el INTO @var_os_name , @var_wk_name, @var_postqual

SELECT @my_ident = NR_WORKER.NR_WK_ID ---n1*
FROM NR_WORKER
WHERE (rtrim(NR_WORKER.NR_WK_NAME) = rtrim(@var_wk_name))
AND (rtrim(NR_WORKER.NR_WD_OS_NAME) = rtrim(@var_os_name))
AND (rtrim(NR_WORKER.NR_WD_POSTQUAL) = rtrim(@var_postqual)) ---n1*

IF @my_ident is NULL
INSERT INTO NR_WORKER (NR_WD_OS_NAME, NR_WK_NAME, NR_WD_POSTQUAL)
VALUES (@var_os_name, @var_wk_name, @var_postqual)

print @my_ident --Для проверки значений

END /*--------While-----*/
CLOSE cur_my_el
DEALLOCATE cur_my_el

Столбец NR_WORKER.NR_WK_ID идентификатор со свойством identity.
Участок кода *n1 предназначен для исключения дублирующихся строк. Соответственно, если
новая прочитанная из IMPORT_NR_ELECTR строка не имеет дублирующих значений в таблице
NR_WORKER (IF @my_ident is NULL), происходит вставка новой строки.

После выполнения данной процедуры, получаем:
Message
1
1
1
1
1
1
...

Получается, что переменной @myident присвоилось значение 1 - идентификатор первой вставленной строки. По отношению к логическому условию для первой записи дубликатов нет.
Для проверки вызывал в коде команду Exists(...), она как и положено вернула false.

в то же время, если заменить *n1 на

set @my_ident = (SELECT NR_WORKER.NR_WK_ID
FROM NR_WORKER
WHERE (rtrim(NR_WORKER.NR_WK_NAME) = rtrim(@var_wk_name))
AND (rtrim(NR_WORKER.NR_WD_OS_NAME) = rtrim(@var_os_name))
AND (rtrim(NR_WORKER.NR_WD_POSTQUAL) = rtrim(@var_postqual)))

то все работает как полагается.

Подскажите, пожалуйста, в чем же различие между командами set и select? Прежде в подобных ситуациях с select проблем не возникало.
9 июл 09, 11:28    [7395282]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
автор
Требуется исключить дублирующие строки.


Какой кошмар... Дубли исключают запросом INSERT ... SELECT ... FROM ... WHERE NOT EXISTS...
9 июл 09, 11:34    [7395358]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
MB_SQL_CM,

а что мешает просто один INSERT ... SELECT ... написать?
9 июл 09, 11:35    [7395369]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
i2akai1
Member

Откуда: Петербург
Сообщений: 217
MB_SQL_CM,

Тоже сталкивался с этим
Похоже что, если в select переменной присваивается значение, и при этом в нем есть from,
то значение присвоится только если в результирующей выборке есть хотя бы одна строка

если строк нет (пустое табличное выражение) то у переменной останется то значение
которое было до этого
9 июл 09, 11:35    [7395373]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
i2akai1
MB_SQL_CM,

Тоже сталкивался с этим


C этим сталкиваются все, кто ленится читать документацию. ;)

If the SELECT statement returns no rows, the variable retains its present value. If expression is a scalar subquery that returns no value, the variable is set to NULL.


Сообщение было отредактировано: 9 июл 09, 11:59
9 июл 09, 11:38    [7395389]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
1. зачем вообще курсор при таком построении цикла то???
-------------------------------------
Jedem Das Seine
9 июл 09, 11:38    [7395393]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
i2akai1
Member

Откуда: Петербург
Сообщений: 217
pkarklin,

там слишком много :) все сразу и не усвоишь - а так напоролся на грабли, проверил, узнал :)
9 июл 09, 11:41    [7395410]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
MB_SQL_CM
Member

Откуда:
Сообщений: 71
i2akai1
MB_SQL_CM,

Тоже сталкивался с этим
Похоже что, если в select переменной присваивается значение, и при этом в нем есть from,
то значение присвоится только если в результирующей выборке есть хотя бы одна строка

если строк нет (пустое табличное выражение) то у переменной останется то значение
которое было до этого


Спасибо.

iap
MB_SQL_CM,
а что мешает просто один INSERT ... SELECT ... написать?


Я сильно сократил код, чтобы не перегружать вас лишней информацией.
9 июл 09, 11:48    [7395482]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
даже если так, то все равно куча лишних телодвижений для организации цикла по курсору :)
-------------------------------------
Jedem Das Seine
9 июл 09, 11:57    [7395565]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
MB_SQL_CM
Я сильно сократил код, чтобы не перегружать вас лишней информацией.


Вот и напрасно.
9 июл 09, 11:58    [7395572]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
MB_SQL_CM
Member

Откуда:
Сообщений: 71
Maxx
даже если так, то все равно куча лишних телодвижений для организации цикла по курсору :)
-------------------------------------
Jedem Das Seine


А что не так? Если знаете способ лучше, буду благодарен за подсказку. Я в этом деле еще новичок.
9 июл 09, 12:01    [7395600]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
declare @kol int
select @kol = count (*) from IMPORT_NR_ELECTR

declare @i int
set @i = 0

WHILE @i < @kol /*----цикл-----------*/
select @i = @i + 1

вот ето фсе, заменяется проверкой @@FETCH_STATUS

И все таки , навренотам можно обойтись и вообще без курсора
-------------------------------------
Jedem Das Seine
9 июл 09, 12:06    [7395628]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33339
Блог
MB_SQL_CM
Пишу хранимую процедуру в MS SQL SERVER 2005 для импорта данных из одной таблицы в другую. Требуется исключить дублирующие строки

insert [другая таблица](...)
select distinct ...
  from [таблица источник]
?
9 июл 09, 12:06    [7395632]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
MB_SQL_CM
Member

Откуда:
Сообщений: 71
Maxx
declare @kol int
select @kol = count (*) from IMPORT_NR_ELECTR

declare @i int
set @i = 0

WHILE @i < @kol /*----цикл-----------*/
select @i = @i + 1

вот ето фсе, заменяется проверкой @@FETCH_STATUS

И все таки , навренотам можно обойтись и вообще без курсора
-------------------------------------
Jedem Das Seine


Понял, спасибо.
9 июл 09, 12:07    [7395640]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
MB_SQL_CM
Member

Откуда:
Сообщений: 71
Критик
MB_SQL_CM
Пишу хранимую процедуру в MS SQL SERVER 2005 для импорта данных из одной таблицы в другую. Требуется исключить дублирующие строки

insert [другая таблица](...)
select distinct ...
  from [таблица источник]
?


Чтобы закрыть уже эту тему повторю, что код переделан для простоты. Строго говоря, такого insert там вообще нет. Я преследовал цель получить ответ на свой вопрос, и я его получил. Всем спасибо.
9 июл 09, 12:14    [7395674]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
rata
Member

Откуда:
Сообщений: 130
i2akai1

если строк нет (пустое табличное выражение) то у переменной останется то значение
которое было до этого

С этим сталкивался каждый из наших новых програмсистов без исключения. И именно в курсоре :-)
9 июл 09, 12:33    [7395806]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31168
pkarklin
Какой кошмар... Дубли исключают запросом INSERT ... SELECT ... FROM ... WHERE NOT EXISTS...
А не сталкивались с такими случаями?

При выполнении:
insert MyTable(id, num)
select @id, @num
where not exists(select 1 from MyTable where id = @id)
Возникает ошибка:

Violation of PRIMARY KEY constraint 'PK_MyTable'. Cannot insert duplicate key in object 'dbo.MyTable'.

поле id типа int, PK_MyTable(id)

Сервер 2008 без SP и CU:
select @@VERSION
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64)
Jul 9 2008 14:17:44
Copyright (c) 1988-2008 Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.0 <X64> (Build 6001: Service Pack 1)


Думал, что это надёжный код.
10 июл 09, 10:05    [7400289]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
alexeyvg,

а триггеры у MyTable есть?
10 июл 09, 10:07    [7400298]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
У себя

Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) 
Mar 29 2009 10:27:29
Copyright (c) 1988-2008 Microsoft Corporation
Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)

не могу воспроизвести.
10 июл 09, 10:12    [7400324]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> А не сталкивались с такими случаями?
>
> При выполнении:
>
> insert MyTable(id, num)
> select @id, @num
> where not exists(select *1* from MyTablewhere id = @id)
>
> Возникает ошибка:
>
> Violation of PRIMARY KEY constraint 'PK_MyTable'. Cannot insert
> duplicate key in object 'dbo.MyTable'.

> Думал, что это надёжный код.

при read uncommitted такое получить легко можно.
теоретически, можно, наверное, и при read committed тоже, но это хитрее уже.

Posted via ActualForum NNTP Server 1.4

10 июл 09, 10:23    [7400393]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Помнится, много раз обсуждали уже.
Например, здесь: Проверка дубликатов
10 июл 09, 10:38    [7400477]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31168
iap
alexeyvg,

а триггеры у MyTable есть?
Нету.

pkarklin
У себя

Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) 
Mar 29 2009 10:27:29
Copyright (c) 1988-2008 Microsoft Corporation
Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)

не могу воспроизвести.

Ну, я тоже не могу :-)

В логах клиента (веб-сервер) такая ошибка. Клиент просто вызывает ХП, внутри ХП этот код.
10 июл 09, 11:07    [7400635]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31168
daw
при read uncommitted такое получить легко можно.
теоретически, можно, наверное, и при read committed тоже, но это хитрее уже.
Там на коннекте нету read uncommitted

iap
Помнится, много раз обсуждали уже.
Например, здесь: Проверка дубликатов
Спасибо за ссылку.

Понятно, что залочить-то всю таблицу легко :-)

Я хотел, чтоб сервер оптимальную блокировку использовал. В данном случае, наверное, нужна блокировка типа диапазона индекса, страницы индекса?
10 июл 09, 11:13    [7400678]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
alexeyvg
В логах клиента (веб-сервер) такая ошибка. Клиент просто вызывает ХП, внутри ХП этот код.


Эээ... Паралелльный запуск двух ХП? SERIALIZABLE м.б.?
10 июл 09, 11:14    [7400688]     Ответить | Цитировать Сообщить модератору
 Re: Различия между операторами Set и Select  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31168
pkarklin
Эээ... Паралелльный запуск двух ХП? SERIALIZABLE м.б.?
Ну да, там, похоже, ошибка в коде клиента...

pkarklin
SERIALIZABLE м.б.?
Ну да, наверное...

Просто мне тут непонятно. Если я напишу так:
insert MyTable(id, num)
select @id, @num
where not exists(select 1 from MyTable WITH(SERIALIZABLE) where id = @id)
то что сервер будет лочить-то? Записи ведь ещё нету?

Или он залочит диапазоны ключей, соответствующие условиям в подзапросе exists()?
10 июл 09, 11:25    [7400760]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить