Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
player95 Member Откуда: Сообщений: 21 |
Доброго времени суток всем! К сожалению мне плоховато дается SQL. В общем то проблема следующая. Есть у меня небольшая табличка. Есть там столбцы "Дата" и "Смена". Дата пишется со временем, дата особого значения не имеет, а вот время да. Есть 3 варианта: XXXX-XX-XX 00:00:00.000, XXXX-XX-XX 08:00:00.000 и XXXX-XX-XX 16:00:00.000. В зависимости от того какое из этих времен стоит должно быть значение 1,2 или 3 в столбике "Смена". Написал я следующий код: USE [DBCurs] GO /****** Object: Trigger [dbo].[Number_Smena] Script Date: 08.03.2017 15:58:01 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --==================================== -- Create database trigger template --==================================== ALTER TRIGGER [dbo].[Number_Smena] ON [dbo].[РабочийПроцесс] AFTER INSERT, UPDATE AS BEGIN IF (select cast(dbo.РабочийПроцесс.Дата as time) [time] FROM dbo.РабочийПроцесс )=convert(time,'00:00',101) UPDATE dbo.РабочийПроцесс SET Смена = 1 WHERE Смена IN(SELECT Смена) ELSE IF (select cast(dbo.РабочийПроцесс.Дата as time) [time] FROM dbo.РабочийПроцесс)=convert(time,'08:00',101) UPDATE dbo.РабочийПроцесс SET Смена = 2 ELSE UPDATE dbo.РабочийПроцесс SET Смена = 3 END Вытаскиваю тут время из datetime, проверяю его и соответственно присваиваю значение. Если запускать этот код просто как запрос, то значения меняются. А вот если запускать его триггером, то вылезает ошибка: Строки не были обновлены. Данные в строке 3 не были зафиксированы. Источник ошибки: .Net SqlClient Data Provider. Сообщение об ошибке: Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения. Выполнение данной инструкции было прервано. Насколько я понял по гуглу, проблема моя в том, что этот триггер будет работать только если в таблице есть одна строка, а если их несколько то запрос возвращает несколько значений и соответственно падает. Далее насколько я понял, проблема решается с помощью команд IN, JOIN или EXISTS, но вот как их применить кокнретно к своему случая я вообще не понимаю. В интернете есть примеры, но по ним к сожалению не получается. |
8 мар 17, 14:06 [20274395] Ответить | Цитировать Сообщить модератору |
player95 Member Откуда: Сообщений: 21 |
Вот это лишнее в коде, осталось после какой то очередной попытки решить проблему |
||
8 мар 17, 14:10 [20274402] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
Поведай нам, страдалец, чего ты хотел ЭТИМ сказать? Или у тя в dbo.РабочийПроцесс ОДНА строка? |
||
8 мар 17, 14:26 [20274443] Ответить | Цитировать Сообщить модератору |
player95 Member Откуда: Сообщений: 21 |
Строк несколько, хотел сравнить время. Вот так сейчас переделал, вроде работает: USE [DBCurs] GO /****** Object: Trigger [dbo].[Number_Smena] Script Date: 08.03.2017 16:28:50 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --==================================== -- Create database trigger template --==================================== ALTER TRIGGER [dbo].[Number_Smena] ON [dbo].[РабочийПроцесс] AFTER INSERT, UPDATE AS BEGIN IF (select cast(Дата as time) [time] FROM inserted )=convert(time,'00:00',101) UPDATE dbo.РабочийПроцесс SET Смена = 1 ELSE IF (select cast(Дата as time) [time] FROM inserted)=convert(time,'08:00',101) UPDATE dbo.РабочийПроцесс SET Смена = 2 ELSE UPDATE dbo.РабочийПроцесс SET Смена = 3 END |
8 мар 17, 14:36 [20274467] Ответить | Цитировать Сообщить модератору |
Massa52 Member Откуда: Сообщений: 382 |
player95, Тут у тебя может вернуться несколько значениий (select cast(Дата as time) [time] FROM inserted ) И ты эти несколько сравниваешь со скалярным(одним) выражением. Результат - тяжело представить. - inserted - это тоже таблица. Там не обязательно одна строка. |
8 мар 17, 14:44 [20274490] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
Поверь мне - это иллюзия. Твой опус не может "работать". |
||
8 мар 17, 15:25 [20274626] Ответить | Цитировать Сообщить модератору |
player95 Member Откуда: Сообщений: 21 |
Да я уже посмотрел, если редактировать или добавлять несколько строк то проблемы. |
8 мар 17, 15:28 [20274632] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
ALTER TRIGGER [dbo].[Number_Smena] ON [dbo].[РабочийПроцесс] AFTER INSERT, UPDATE AS BEGIN with i as ( select * , сменаX = case cast(Дата as time) when convert(time,'00:00',101) then 1 when convert(time,'08:00',101) then 2 else 3 end from inserted ) update t set Смена = i.сменаX from [dbo].[РабочийПроцесс] as t inner join i on i.id = t.id where exists( select t.Смена except select i.сменаX ) ; END |
8 мар 17, 15:35 [20274657] Ответить | Цитировать Сообщить модератору |
player95 Member Откуда: Сообщений: 21 |
Большое спасибо! А вы можете, кратко пояснить как все это работает?with i as ( select *//with i as не очень понимаю как работает , сменаX = case cast(Дата as time) when convert(time,'00:00',101) then 1 when convert(time,'08:00',101) then 2 else 3 end from inserted ) Тут насколько я понимаю создаем переменную, в которой проверяем само условие? update t set Смена = i.сменаX from [dbo].[РабочийПроцесс] as t inner join i on i.id = t.id where exists( select t.Смена except select i.сменаX ) ; Первая строка update, обновляем то что получилось после прохождения условия, а вот у 2 последних строк, тоже не очень понимаю механизм работы. |
8 мар 17, 15:53 [20274750] Ответить | Цитировать Сообщить модератору |
Шыфл Member Откуда: Прага Сообщений: 776 |
player95,with i as ( select * , сменаX = case cast(Дата as time) when convert(time,'00:00',101) then 1 when convert(time,'08:00',101) then 2 else 3 end from inserted ) Это код объявляет таблицу i, в которую помещает * из инсертед + вычисляет сменаХ для каждой записи. Далее в коде идёт update [dbo].[РабочийПроцесс] as t update t set Смена = i.сменаX from [dbo].[РабочийПроцесс] as t inner join i on i.id = t.id where exists( select t.Смена except select i.сменаX ) Где t соединяется с i через id А последняя строчка - это выбор того, где Смена ещё не заполнена. Может быть и что-то вроде where t.Смена is null |
8 мар 17, 19:33 [20275275] Ответить | Цитировать Сообщить модератору |
player95 Member Откуда: Сообщений: 21 |
Спасибо всем отписавшимся! |
9 мар 17, 19:05 [20279153] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |