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

Откуда: Москва
Сообщений: 366
Добрый день. Есть подозрение на странную работу группировки. Или даже не знаю на что. Подскажите.
Ситуация такая:
в триггере "FOR DELETE" одной таблицы имеется код такого вида:

INSERT INTO tp1 (...)
SELECT ...
FROM
   (SELECT 1 as party, ... FROM deleted d inner join tbmain on d.id = tbmain.id
   UNION ALL
   SELECT 2 as party, ... FROM deleted d inner join tbmain on d.id = tbmain.id) as t1
GROUP BY ...

INSERT INTO tp2 (...)
SELECT ...
FROM
   (SELECT 1 as party, ... FROM deleted d inner join tbmain on d.id = tbmain.id
   UNION ALL
   SELECT 2 as party, ... FROM deleted d inner join tbmain on d.id = tbmain.id) as t1

Запросы отличаются только группировкой, и тем, что вставка идет в разные таблицы. Может ли быть такое, что первый запрос вставит некоторое число записей в таблицу, а второй - 0 (ноль), т.е. ничего не вставит?
Спасибо.
3 июн 09, 15:55    [7261273]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
Сид
Member

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

В вопросе всё самое главное заменено на "..."
3 июн 09, 15:59    [7261294]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
iap
Member

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

это триггер для какой таблицы (Вы пишете "одной таблицы")?

у tp2 триггеры есть?
3 июн 09, 16:05    [7261334]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
sander1
Member

Откуда: Москва
Сообщений: 366
У "tp1", "tp2" триггеров нет. "Одна таблица" - это таблица, в указанном коде не фигурирующая.

По поводу "самое главное заменено", значит, видимо ваш ответ на мой вопрос звучит как "может". Потому что вопрос фактически заключается в следующем:
"может ли вернуть один запрос n записей, а второй 0,
если они отличаются только выражениями select и наличием группировки".

Не хотелось приводить оригинальный громоздкий вариант, но чтобы не было вопросов, вот он:

ALTER   TRIGGER [dbo].[НПеремСпецDelete1] ON [dbo].[НПеремСпец] 
FOR  DELETE
AS
BEGIN

INSERT INTO ТоварныйПоток (process_id, nestlevel, T_U, RM, QuantityPlus, InputPlus, OutputPlus, OutputReadyPlus, ReserveCell, ReserveCellAction, DocType, DocID, IsInsert, TableAction)
SELECT sp_id, nestlevel, Товар_У, RM, SUM(QuantityPlus), SUM(InputPlus), SUM(OutputPlus), SUM(OutputReadyPlus), 0 as ReserveCell, 0 as ReserveCellAction, DocType, DocID, IsInsert, TableAction
FROM
(
	SELECT @@SPID as sp_id, @@NESTLEVEL as nestlevel, Товар_У, RMOUT as RM,
		Кол as QuantityPlus,
		0 as InputPlus,
		-Кол*(CAST(Отпущено as int) - 1)*(CAST(Принято as int) - 1) as OutputPlus,
		0 as OutputReadyPlus,
	0 as ReserveCell, 
	0 as ReserveCellAction,
	'ПРМ' as DocType, НПерем.Me_U as DocID, 0 as IsInsert, 'd' as TableAction
	FROM deleted d
	INNER JOIN НПерем ON d.Par_U = НПерем.Me_U --остатки для RMOUT
	UNION ALL
	SELECT @@SPID as sp_id, @@NESTLEVEL as nestlevel, Товар_У, RMIN as RM,
		-Кол*CAST(Отпущено as int)*CAST(Принято as int) as QuantityPlus,
		Кол*CAST(Отпущено as int)*(CAST(Принято as int) - 1) as InputPlus,
		0 as OutputPlus,
		0 as OutputReadyPlus,
	0 as ReserveCell,
	0 as ReserveCellAction,
	'ПРМ' as DocType, НПерем.Me_U as DocID, 0 as IsInsert, 'd' as TableAction
	FROM deleted d
	INNER JOIN НПерем ON d.Par_U = НПерем.Me_U --остатки для RMIN
) as t1
GROUP BY sp_id, nestlevel, Товар_У, RM, DocType, DocID, IsInsert, TableAction --Группировка вводится здесь для случая внутрискладского перемещения товара по ячейкам, когда RMIN = RMOUT

INSERT INTO ТоварныйПоток2 (process_id, nestlevel, T_U, RM, QuantityPlus, InputPlus, OutputPlus, OutputReadyPlus, ReserveCell, ReserveCellAction, DocType, DocSpecID, DocID, IsInsert, TableAction, DocItem)
SELECT sp_id, nestlevel, Товар_У, RM, QuantityPlus, InputPlus, OutputPlus, OutputReadyPlus, 0 as ReserveCell, 0 as ReserveCellAction, DocType, DocSpecID, DocID, IsInsert, TableAction, Основание
FROM
(
	SELECT @@SPID as sp_id, @@NESTLEVEL as nestlevel, Товар_У, RMOUT as RM,
		Кол as QuantityPlus,
		0 as InputPlus,
		-Кол*(CAST(Отпущено as int) - 1)*(CAST(Принято as int) - 1) as OutputPlus,
		0 as OutputReadyPlus,
	0 as ReserveCell, 
	0 as ReserveCellAction,
	'ПРМ' as DocType, d.Me_U as DocSpecID, НПерем.Me_U as DocID, 0 as IsInsert, 'd' as TableAction, НПерем.Основание
	FROM deleted d
	INNER JOIN НПерем ON d.Par_U = НПерем.Me_U --остатки для RMOUT
	UNION ALL
	SELECT @@SPID as sp_id, @@NESTLEVEL as nestlevel, Товар_У, RMIN as RM,
		-Кол*CAST(Отпущено as int)*CAST(Принято as int) as QuantityPlus,
		Кол*CAST(Отпущено as int)*(CAST(Принято as int) - 1) as InputPlus,
		0 as OutputPlus,
		0 as OutputReadyPlus,
	0 as ReserveCell,
	0 as ReserveCellAction,
	'ПРМ' as DocType, d.Me_U as DocSpecID, НПерем.Me_U as DocID, 0 as IsInsert, 'd' as TableAction, НПерем.Основание
	FROM deleted d
	INNER JOIN НПерем ON d.Par_U = НПерем.Me_U --остатки для RMIN
) as t1
--...
Триггеров у ТоварныйПоток и ТоварныйПоток2 нет!
3 июн 09, 16:15    [7261405]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
sander1
"может ли вернуть один запрос n записей, а второй 0,
если они отличаются только выражениями select и наличием группировки".
Привожу пример (такое поведение документировано, между прочим!):
SET NOCOUNT ON;
DECLARE @T TABLE(X INT);
DECLARE @X INT;
SELECT @X=COUNT(*) FROM @T;
PRINT @@ROWCOUNT;
SELECT @X=X FROM @T;
PRINT @@ROWCOUNT;
3 июн 09, 16:54    [7261666]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
daw
Member

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

> Не хотелось приводить оригинальный громоздкий вариант, но чтобы не было
> вопросов, вот он:

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

Posted via ActualForum NNTP Server 1.4

3 июн 09, 18:04    [7262212]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
конечно может, при несоответствии вставляемых данных структуре таблицы...

для спящего время бодрствования равносильно сну
3 июн 09, 18:36    [7262345]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
А вот этот запрос что возвращает?
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_CATALOG=DB_NAME() AND TABLE_NAME=N'ТоварныйПоток2' AND TABLE_TYPE='BASE TABLE';
Как Вы определяете, что в ТоварныйПоток2 ничего не вставляется?
На всякий случай схему у таблицы всегда задавайте.
3 июн 09, 18:38    [7262351]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
sander1
Member

Откуда: Москва
Сообщений: 366
По поводу ошибок - восстановить картину, были ли они, к сожалению, скорее всего уже не удастся (много пользователей, и расхождения поймались относительно давно). Данные в обе таблицы вставляются достаточно давно, полгода; несколько миллионов записей было добавлено, и на них приходятся три таких "нестыковки", когда в одну что-то попало, а в другую нет.
3 июн 09, 18:45    [7262381]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
sander1
несколько миллионов записей было добавлено, и на них приходятся три таких "нестыковки", когда в одну что-то попало, а в другую нет.
Может, добавилось нормально, а потом удалили?
3 июн 09, 18:51    [7262392]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
sander1
Member

Откуда: Москва
Сообщений: 366
То-то и странно, что нет! Таблицы, куда вставляются данные, пользователям недоступны, и используются всего лишь в одной процедуре, в которой - в первую очередь - логгируются новые данные по ним. Странно потому, что, насколько я понимаю, операторы в триггере в одной транзакции идут, значит, на сколько я понимаю, появление ошибки не могло привести к расхождению.
3 июн 09, 19:04    [7262431]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
iap
Member

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

это Вы триггер процедурой называете? Или ещё и какая-то процедура есть?
3 июн 09, 19:12    [7262447]     Ответить | Цитировать Сообщить модератору
 Re: Группировка и количество записей  [new]
sander1
Member

Откуда: Москва
Сообщений: 366
Да нет, речь о другой процедуре. В триггере только вставка, а там - логгирование данных двух таблиц, куда шла вставка, обработка на основании данных таблиц, а потом последовательное удаление из одной и другой (два оператора delete подряд). Процедура вызывается в конце приведенного триггера.

Ладно, будем разбираться. Всем спасибо.
4 июн 09, 10:32    [7263727]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить