Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/88: Рейтинг темы: голосов - 88, средняя оценка - 4.60
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220

Проверка данных при вводе в таблицу

09.03.2017, 11:55. Показов 18310. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть таблица:
T-SQL
1
2
3
4
5
6
7
8
9
CREATE TABLE [dbo].[EmploymentHistory](
    [ehID][bigint] IDENTITY(1,1) NOT NULL, -- ID
    [ehHousing] [tinyint] NOT NULL, -- Корпус
    [ehNumberClassrooms] [smallint] NOT NULL, -- Номер
    [ehDate][date] NOT NULL DEFAULT(getdate()), -- Дата
    [ehStartTime][time] NOT NULL, -- время с
    [ehEndOfTime][time] NOT NULL, -- время до
    CONSTRAINT PK_IDEmploymentHistory PRIMARY KEY(ehID)
) ON [PRIMARY]
Как при ее заполнении сделать так чтобы нельзя было на одно и то же время в одну и ту же аудиторию в один день добавлять запись?

Например:
1 1 101 09.03.2017 8:00 10:00
2 1 101 09.03.2017 8:00 10:00 - ошибка
3 1 101 09.03.2017 9:00 11:00 - ошибка

Если делать поля уникальными или ключём то третья строка не будет ошибкой, на сколько я понимаю.
Если делать триггер то я не до конца понимаю как именно описать условие. У меня получилось следующее:
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TRIGGER Trigger_EmploymentHistory_ReservationClassroom ON EmploymentHistory
AFTER INSERT, UPDATE
AS
BEGIN
  IF EXISTS(
    SELECT ehHousing, ehNumberClassrooms, ehDate, ehStartTime, ehEndOfTime FROM inserted i
    JOIN EmploymentHistory e ON e.ehHousing = i.ehHousing AND e.ehNumberClassrooms = i.ehNumberClassrooms
    AND e.ehDate = i.ehDate AND ((e.ehStartTime = i.ehStartTime AND e.ehEndOfTime = i.ehEndOfTime) OR i.ehStartTime > e.ehEndOfTime)
  )
  BEGIN
    RAISERROR('Нельзя занять один кабинет на одно время несколько раз', 16, 1)
    RETURN
  END
END
Но ведь если там до поля 1 будет какое нибудь поле, например:
0 1 101 08.03.2017 16:00 20:00 (не будем обращать внимание на то что с ключ записан не корректно)
1 1 101 09.03.2017 8:00 10:00
2 1 101 09.03.2017 8:00 10:00 - ошибка
3 1 101 09.03.2017 9:00 11:00 - ошибка

Получаем что 09.03.2017 можно еще скажем с 7:00 до 8:00 занять аудиторию.

Можно ли как-то сделать ограничение в самой базе данных или это надо учитывать при написании программы для этой базы?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.03.2017, 11:55
Ответы с готовыми решениями:

При вводе данных в первую таблицу, создать строку с ID во второй
Есть две таблицы:` reception` и `send`, они оба связянны между собой с помощю ( reception) id и (send) reception_id. Вопрос! как...

Проверка типа данных при вводе
Задача: реализовать проверку на то, что пользователь ввёл целое число. Нашёл это: //Зачем использовать шаблон? template<class...

Проверка типа данных при вводе
Приветствую! Требуется помощь в решении такой задачки. Нужно чтобы при нажатии на кнопку "ОК" выводилось сообщение о неправильном...

12
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.03.2017, 12:37
Ruta, в предыдущей вашей теме я уже намекал, что конструкция raiserror...return в after-триггере не запрещает модификации данных, только генерирует ошибку.

Чтобы запретить модификацию данных триггер должен выглядеть так:
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TRIGGER Trigger_EmploymentHistory_ReservationClassroom ON EmploymentHistory
AFTER INSERT, UPDATE
AS
BEGIN
  IF EXISTS(
    SELECT
     *
    FROM inserted i
    JOIN EmploymentHistory e ON e.ehHousing = i.ehHousing AND e.ehNumberClassrooms = i.ehNumberClassrooms AND e.ehDate = i.ehDate AND e.ehID <> i.ehID
    WHERE
     e.ehStartTime <= i.ehEndOfTime AND e.ehEndOfTime >= i.StartTime
  )
  THROW 50000, 'Нельзя занять один кабинет на одно время несколько раз', 16;
END;
2
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
09.03.2017, 12:58  [ТС]
invm,
Цитата Сообщение от invm Посмотреть сообщение
не запрещает модификации данных, только генерирует ошибку
ну так мне и надо ошибку сгенерировать если будет введено время на которое кабинет уже забронирован, зачем запрещать модификацию данных? пусть модифицируют, только чтобы дата и время для одного кабинета не совпадали. Я если честно не поняла что конкретно вы имели в виду

Извиняюсь за тупые вопросы, мне просто очень надо срочно закончить, а из практики работы с бд и субд у меня только аксес.

Ну и раз пошло на то, подскажите а триггер можно сделать так чтобы если в одной колонке введено определенное значение (например если поле не равно 3), то второй колонке присвоилось NULL
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.03.2017, 13:08
Цитата Сообщение от Ruta Посмотреть сообщение
ну так мне и надо ошибку сгенерировать если будет введено время на которое кабинет уже забронирован, зачем запрещать модификацию данных?
Ну т.е. пусть будет только ошибка, а в таблице останутся некорректные данные?
Цитата Сообщение от Ruta Посмотреть сообщение
подскажите а триггер можно сделать так чтобы если в одной колонке введено определенное значение (например если поле не равно 3), то второй колонке присвоилось NULL
Можно. Такие вещи лучше делать в триггерах nstead of, а не after.
1
1040 / 856 / 335
Регистрация: 08.12.2016
Сообщений: 3,283
09.03.2017, 13:15
Цитата Сообщение от invm Посмотреть сообщение
Ну т.е. пусть будет только ошибка, а в таблице останутся некорректные данные?
приложение, полагаю, откатит транзакцию и в таблице некорректных данных не будет
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.03.2017, 13:25
Цитата Сообщение от YuryK Посмотреть сообщение
приложение, полагаю, откатит транзакцию и в таблице некорректных данных не будет
Само? Учить его откатывать транзакции не нужно?
А если приложение не управляет транзакциями?
А если меняем данные мимо приложения, то плевать?
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
09.03.2017, 13:34  [ТС]
Цитата Сообщение от invm Посмотреть сообщение
Ну т.е. пусть будет только ошибка, а в таблице останутся некорректные данные?
ну, сервер не давал ввести данные с предыдущем триггером, всегда выдавал ошибку и сохранить не давал
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.03.2017, 13:44
Цитата Сообщение от Ruta Посмотреть сообщение
ну, сервер не давал ввести данные с предыдущем триггером, всегда выдавал ошибку и сохранить не давал
Да неужели?
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use tempdb;
go
 
create table dbo.Test (a int);
go
 
create trigger dbo.trTest_i
on dbo.Test
after insert
as
begin
 if exists(select * from inserted where a < 0)
  begin
   raiserror('Error!!! a < 0 !!!', 16, 1);
   return;
  end;
end;
go
 
insert into dbo.Test values (-1);
go
 
select * from dbo.Test;
go
 
alter trigger dbo.trTest_i
on dbo.Test
after insert
as
begin
 if exists(select * from inserted where a < 0)
  throw 50000, 'Error!!! a < 0 !!!', 16;
end;
go
 
insert into dbo.Test values (-2);
go
 
select * from dbo.Test;
go
 
drop table dbo.Test;
go
1
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
09.03.2017, 13:57  [ТС]
invm, когда скриптом вносишь - я не порверяла, вводил или нет, но когда ручками заполняешь он не дает. Смысл ясен, извините
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.03.2017, 14:08
Ruta, когда "заполняете ручками", приложение, которым это делаете, модифицирует данные в транзакции, которую откатывает в случае ошибки. Происходит это автоматически и прозрачным для вас образом. Именно на такое поведение намекал YuryK.
Но из этого не следует, что все средства работы с данными, в том числе и написанные вами, будут работать аналогичным образом.
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
12.03.2017, 19:13  [ТС]
invm,
Цитата Сообщение от invm Посмотреть сообщение
Такие вещи лучше делать в триггерах nstead of, а не after
немного недопоняла как именно вставить в данные в ту же строку в которую введено предыдущее значение
T-SQL
1
2
3
4
5
6
7
8
9
10
CREATE TRIGGER Trigger_LabTypeOfClassrooms ON Classrooms
INSTEAD OF UPDATE
AS
BEGIN
IF EXISTS(
    SELECT cType FROM inserted i WHERE i.cType = 3 
  )
--THROW 50000, 'Если вы выбираете лабораторный тип аудитории, то надо выбрать лабораторию, которой она принадлежит. И наоборот, если аудиитория не лабораторная, то она не должна принадлежать лаборатории', 16;
    INSERT INTO Classrooms (cLab) VALUE (NULL)
END
так ругается что перед end еще что-то должно быть, а если исспользовать
T-SQL
1
INSERT INTO inserted (cLab) VALUE (NULL)
, то ругается что нельзя там inserted писать.

И вопрос по предыдущим триггерам, там писали UPDATE, то есть при обновлении а INSERT не надо, типо при добавлении что бы тоже срабатывал?
0
1040 / 856 / 335
Регистрация: 08.12.2016
Сообщений: 3,283
13.03.2017, 00:32
Цитата Сообщение от Ruta Посмотреть сообщение
вставить в данные в ту же строку в которую введено предыдущее значение
в триггере INSTEAD OF все изменения сделаны над таблицей inserted, в саму таблицу Classrooms изменения ещё не попали, поэтому надо аккуратно их перенести в настоящую таблицу, перед эти проверив их на допустимость.

З.Ы. не зная структуры написать триггер не могу, но вставлять запись, сплошь состоящую из NULL совершенно не правильно. Это я о
Цитата Сообщение от Ruta Посмотреть сообщение
INSERT INTO Classrooms (cLab) VALUE (NULL)
Добавлено через 5 минут
в триггере INSTEAD OF UPDATE должно быть что-то типа
T-SQL
1
2
3
4
5
6
UPDATE c SET 
  c.cType  = i.cType, 
-- остальные поля таблицы Classrooms, которые могут быть изменены   
FROM
  inserted i
  JOIN Classrooms c ON i.cId = c.cId
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
13.03.2017, 10:49  [ТС]
Таблица аудиторий:
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE [dbo].[Classrooms](
    [cNumber] [smallint] NOT NULL, -- Номер кабинета
    [cHousing] [tinyint] NOT NULL, -- Корпус
    [cFloors] [tinyint]  NOT NULL, -- Этаж =< количество этажей в корпусе (триггер)
    [cWidth][float] NOT NULL, -- Ширина
    [cLength][float] NOT NULL, -- Длина
    [cType][tinyint] NOT NULL, -- Тип помещения
    [cLab] [smallint] NULL, -- Лаборатория -- должна принадлежать Факультету (триггер), NUll если тип не равен 3 проверка в программе
    [cFaculty] [tinyint] NULL, -- Факультет
    CONSTRAINT Check_IDClassrooms CHECK (cNumber > 0 and cNumber < 2000),
    CONSTRAINT PK_IDClassrooms PRIMARY KEY(cHousing, cNumber)
) ON [PRIMARY]
Таблица типов аудиторий:
T-SQL
1
2
3
4
5
6
7
CREATE TABLE [dbo].[TypeClassrooms](
    [tcID] [tinyint] NOT NULL, -- ID
    [tcTypeClassrooms] [nvarchar](30) NOT NULL, -- Вид помещения
    [tcHeight][float] NOT NULL, -- Высота помещения
    CONSTRAINT PK_IDTypeClassrooms PRIMARY KEY(tcID),
    CONSTRAINT Unique_tcTypeClassrooms UNIQUE(tcTypeClassrooms)
) ON [PRIMARY]
Хочу сделать чтобы при вводе аудитории, вносишь тип 3 и нельзя было написать в столбик лабораторий NULL (пишется номер лаборатории, которой принадлежит эта аудитория), и наоборот, если тип не равен 3, то в колонку лаборатория писалось NULL.

Или лучше просто сделать чтобы сообщение об ошибке выдавал (это сама сделаюу)?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.03.2017, 10:49
Помогаю со студенческими работами здесь

Соблюдение условий на значение при вводе данных в таблицу через DBGreed
Здравствуйте. Подскажите, пожалуйста, как организовать проверку условия на значение, когда таблица из Access выводится на форму в...

Как при вводе данных в таблицу через форму осуществить переход к следующей непустой строке?
Доброго времени суток! извините, если пишу не там где нужно( я долго искал подходящий раздел но так ничего и не нашел) Я начинающий. учусь...

Как при вводе в одну таблицу данных изменить значение в другой таблице в строке с тем же номером?
Есть БД в access, состоящая из 6 таблиц. Задача - при вводе в одну таблицу данных изменить значение в другой таблице в строке с тем же...

Проверка данных (тип список), список возможных вариантов при вводе вручную
Можно ли в инструменте Проверка данных (при типе данных &quot;Список&quot;) выводить список возможных значений при вводе вручную? Например, если...

Условие при вводе в таблицу
Не могу разобраться.вылазит Ошибка. Вопрос такой. условие на значение в таблице и на форме. Желательно 2 варианта.при вводе значний и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru