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

Исправить ошибку в хранимой процедуре при работе с курсором

28.03.2016, 20:40. Показов 1469. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! есть таблица, заполненная след. образом
Insert into Massage ([ID Client], [ID Massagist], [ID TypeMassage], [Date/Time], [Count]) values (42, 180, 161, '09.02.2016 12:00', 1);
Insert into Massage ([ID Client], [ID Massagist], [ID TypeMassage], [Date/Time], [Count]) values (42, 181, 160, '09.03.2016 15:00', 1);
Insert into Massage ([ID Client], [ID Massagist], [ID TypeMassage], [Date/Time], [Count]) values (43, 181, 160, '09.02.2016 13:00', 2);
Insert into Massage ([ID Client], [ID Massagist], [ID TypeMassage], [Date/Time], [Count]) values (44, 181, 162, '10.03.2016 13:00', 1);

Написала хранимую процедуру с курсором, но всегда вылетает ответ что МАССАЖИСТ ЗАНЯТ, не заходит в то чтобы записать нового. не пойму в чем дело?! помогите пожалуйста
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
CREATE PROCEDURE MyProcedure
 
 @IDclient int,
@IDMassagist int,
 @IDTypeMassage int,
 @Date datetime, 
 @Count int 
 AS
--Объявляем курсор
DECLARE @CURSORs CURSOR
--Заполняем курсор
SET @CURSORs  = CURSOR SCROLL
FOR
SELECT  [ID Client], [ID Massagist], [ID TypeMassage], [Date/Time], [Count]
  FROM  Massage 
--Открываем курсор
OPEN @CURSORs
--Выбираем первую строку
FETCH NEXT FROM @CURSORs INTO @IDclient, @IDMassagist, @IDTypeMassage, @Date, @Count
--Выполняем в цикле перебор строк
WHILE @@FETCH_STATUS = 0
BEGIN
        
  IF  NOT EXISTS (SELECT *  FROM Massage WHERE [Date/Time]=@Date AND [ID Massagist]= @IDMassagist)
    BEGIN
     INSERT INTO Massage ([ID Client], [ID Massagist], [ID TypeMassage], [Date/Time], [Count]) VALUES (@IDclient, @IDMassagist, @IDTypeMassage, @Date, @Count)
     PRINT 'Вы записаны на массаж'
    END 
    ELSE
     PRINT 'Массажист занят'
 
/*Выбираем следующую строку*/
 FETCH NEXT FROM @CURSORs INTO @IDclient, @IDMassagist, @IDTypeMassage, @Date, @Count
 END
CLOSE @CURSORs
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.03.2016, 20:40
Ответы с готовыми решениями:

Проблема с курсором в хранимой процедуре
добрый день уважаемые. Нужна помощь. Написал хранимую процедуру для добавления записей в таблицу операций если удовлетворяется условие....

Исправить ошибку компиляции C2371 при работе с указателями
Привет :) Проходу тему "Указатели", написал программу. Компилятор ругается, не знаю почему. Сделал всё так как написано в примере....

Ошибка при передаче параметра хранимой процедуре
Здравствуйте! Возникла ошибка "EDatabaseError with message'IBstoredProc1:Parameter 'str' not found'" при попытке передать значение...

9
шапоклякистка 8-го дня
 Аватар для texnik-san
3681 / 2241 / 391
Регистрация: 26.06.2015
Сообщений: 4,647
Записей в блоге: 1
28.03.2016, 20:56
Смотрите. Вы проверяете условие

SQL
1
NOT EXISTS (SELECT *  FROM Massage WHERE [DATE/TIME]=@DATE AND [ID Massagist]= @IDMassagist)
А переменные @Date и @IDMassagist у вас получают значения из текущей строки запроса
SQL
1
2
SELECT  [ID Client], [ID Massagist], [ID TypeMassage], [DATE/TIME], [COUNT]
  FROM  Massage
Т.е. вы все время проверяете существование в таблице Massage пары [Date/Time] и [ID Massagist], которая в этой таблице ЕСТЬ.

Добавлено через 1 минуту
Понятно, что при этом NOT EXISTS всегда ложное и массажист всегда занят.
1
2 / 2 / 0
Регистрация: 14.09.2014
Сообщений: 82
28.03.2016, 22:05  [ТС]
вы не подскажите как исправить?

Переписала немного, но все равно работает не правильно
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
CREATE PROCEDURE MyProcedure @IDclient int, @IDMassagist int, @IDTypeMassage int, @Date datetime, @Count int 
 AS
--Объявляем курсор
DECLARE @CURSORs CURSOR
--Заполняем курсор
SET @CURSORs  = CURSOR SCROLL
FOR
SELECT [ID Client], [ID Massagist], [ID TypeMassage], [Date/Time], [Count]
  FROM Massage
--Открываем курсор
OPEN @CURSORs
--Выбираем первую строку
FETCH NEXT FROM @CURSORs INTO @IDclient, @IDMassagist, @IDTypeMassage, @Date, @Count
--Выполняем в цикле перебор строк
WHILE @@FETCH_STATUS = 0
BEGIN
       
  IF (SELECT Massagist.Surname FROM Massagist WHERE [ID Massagist] = @IDMassagist) ='Якубова' 
    BEGIN
     INSERT INTO Massage  VALUES (@IDclient, @IDMassagist, @IDTypeMassage, @Date, @Count)
     PRINT 'Вы записаны на массаж'
    END 
    ELSE
     PRINT 'Этот массажист занят'
 
/*Выбираем следующую строку*/
 FETCH NEXT FROM @CURSORs INTO @IDclient, @IDMassagist, @IDTypeMassage, @Date, @Count
 END
CLOSE @CURSORs
0
шапоклякистка 8-го дня
 Аватар для texnik-san
3681 / 2241 / 391
Регистрация: 26.06.2015
Сообщений: 4,647
Записей в блоге: 1
28.03.2016, 23:02
Цитата Сообщение от Kris123 Посмотреть сообщение
вы не подскажите как исправить?
Я попробую, но отнеситесь к моей попытке очень критически: я не умею писать на языке SQL Server. Когда чужой код читаю - понимаю, как правило (для чтения знания другого диалекта SQL достаточно). А сама еще не пишу. Надеюсь, что "пока не пишу".

Давайте для начала проговорим, чего вы хотите добиться от процедуры. По второй попытке я поняла так: процедура принимает на входе ID клиента, который хочет записаться на массаж, ID массажиста, к которому хочет записаться клиент, ID типа массажа, который хотел бы получить клиент, и дату. И процедура должна проверить, не занят ли этот массажист в этот день, и если не занят - то записать клиента на массаж, а если занят - выдать сообщение. Правильно?

Если да - то, по моим представлениям, для такой задачи курсор вообще не нужен. Достаточно проверки NOT EXISTS. Синтаксис проверяйте, могут быть ошибки!

SQL
1
2
3
4
5
6
7
8
9
CREATE PROCEDURE MyProcedure @IDclient INT, @IDMassagist INT, @IDTypeMassage INT, @DATE datetime, @COUNT INT 
 AS
IF  NOT EXISTS (SELECT *  FROM Massage WHERE [DATE/TIME]=@DATE AND [ID Massagist]= @IDMassagist)
    BEGIN
     INSERT INTO Massage ([ID Client], [ID Massagist], [ID TypeMassage], [DATE/TIME], [COUNT]) VALUES (@IDclient, @IDMassagist, @IDTypeMassage, @DATE, @COUNT)
     PRINT 'Вы записаны на массаж'
    END 
 ELSE
     PRINT 'Этот массажист в этот день занят, выберите другого массажиста или другой день'
1
2 / 2 / 0
Регистрация: 14.09.2014
Сообщений: 82
28.03.2016, 23:07  [ТС]
да, вы поняли правильно, т.е. вызов такой:
T-SQL
1
EXEC MyProcedure 41, 180, 162, '09.02.2016 12:00', 1
41-айди клиента, 180-айди массажиста, 162-айди типа массажа, дата, 1-кол-во часов
чтобы понятнее, я уже исправила вот эту часть:
T-SQL
1
2
3
4
5
6
7
8
9
IF (SELECT [ID Massagist] FROM Massage  WHERE [ID Massagist] = @IDMassagist) = 180 
    
     PRINT 'Этот массажист занят'
 
     else
     BEGIN
       INSERT INTO Massage  VALUES (@IDclient, @IDMassagist, @IDTypeMassage, @Date, @Count)
       PRINT 'Вы записаны на массаж'
     END
то есть результат должен быть: Этот массажист занят. у меня появляется чушь.
И да, задание сделать хранимую процедуру с курсором.
0
шапоклякистка 8-го дня
 Аватар для texnik-san
3681 / 2241 / 391
Регистрация: 26.06.2015
Сообщений: 4,647
Записей в блоге: 1
28.03.2016, 23:29
С другой стороны, допустим, клиент хочет к любому массажисту на заданную дату. Тогда курсор нужен, но выбирающий данные не из таблицы массажей, а из таблицы массажистов. Я написала Massagist, вы подставьте праивльное имя таблицы. Опять же, заранее прошу прощения за синтаксические ошибки.

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
CREATE PROCEDURE MyProcedure @IDclient INT, @IDTypeMassage INT, @DATE datetime, @COUNT INT 
 AS
DECLARE @IDMassagist INT
--Объявляем курсор
DECLARE @CURSORs CURSOR
--Заполняем курсор
SET @CURSORs  = CURSOR SCROLL
FOR
SELECT  [ID Massagist]
  FROM  Massagist
--Открываем курсор
OPEN @CURSORs
--Выбираем первую строку
FETCH NEXT FROM @CURSORs INTO @IDMassagist
--Выполняем в цикле перебор строк
WHILE @@FETCH_STATUS = 0
BEGIN
        
  IF  NOT EXISTS (SELECT *  FROM Massage WHERE [DATE/TIME]=@DATE AND [ID Massagist]= @IDMassagist)
    BEGIN
     INSERT INTO Massage ([ID Client], [ID Massagist], [ID TypeMassage], [DATE/TIME], [COUNT]) VALUES (@IDclient, @IDMassagist, @IDTypeMassage, @DATE, @COUNT)
     PRINT 'Вы записаны на массаж'
-- Тут надо прекратить выполнение процедуры, т.к. цель достигнута
     BREAK
    END 
    ELSE
     PRINT 'Этот массажист занят, проверям расписание следующего'
 
/*Выбираем следующую строку*/
 FETCH NEXT FROM @CURSORs INTO @IDclient, @IDMassagist, @IDTypeMassage, @DATE, @COUNT
 END
CLOSE @CURSORs
Добавлено через 5 минут
Ну и дальше, думаю, нужно ждать кого-то, кто лучше меня разбирается в предмете. Я и так уже превысила пределы своей компетентности.
0
2 / 2 / 0
Регистрация: 14.09.2014
Сообщений: 82
28.03.2016, 23:31  [ТС]
тогда как вы предлагаете вызвать процедуру?

если так
T-SQL
1
2
 EXEC MyProcedure 41, 180, 162, '09.02.2016 12:00', 1
  EXEC MyProcedure 44, 181, 161, '10.04.2016 13:00', 1
ругается что аргументов много, если напишу меньше, в случае успеха у меня просто не заполнится таблица Massage
0
шапоклякистка 8-го дня
 Аватар для texnik-san
3681 / 2241 / 391
Регистрация: 26.06.2015
Сообщений: 4,647
Записей в блоге: 1
28.03.2016, 23:42
Во втором варианте? Из аргументов убрать тот, который ID массажиста.

Потом, наверное, нужно при прохождении цикла печатать, какой ID массажиста выбралася, чтобы понять, в чем может быть проблема, почему запись не добавляется. Если ID массажиста пустой - то ошибка в присовении значения переменной. Если ID массажиста есть, а добавления не происходит - значит, в запросе на добавление ошибка.

Добавлено через 3 минуты
Ааа. Кажется, я поняла, где ошибка. В самом конце оператор

SQL
1
FETCH NEXT FROM @CURSORs INTO @IDclient, @IDMassagist, @IDTypeMassage, @DATE, @COUNT
нужно заменить на такой, как в начале

SQL
1
FETCH NEXT FROM @CURSORs INTO @IDMassagist
0
2 / 2 / 0
Регистрация: 14.09.2014
Сообщений: 82
28.03.2016, 23:45  [ТС]
теперь похоже на истину, спасибо большое)
но работает пока что не совсем верно, подумаю
0
шапоклякистка 8-го дня
 Аватар для texnik-san
3681 / 2241 / 391
Регистрация: 26.06.2015
Сообщений: 4,647
Записей в блоге: 1
29.03.2016, 00:01
Надо как-то не только совпадение даты сверять, но и длительность. Если массаж на 3 и длится 2 часа, то на 4 записывать еще никого нельзя.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.03.2016, 00:01
Помогаю со студенческими работами здесь

Почему выдает ошибку при работе с большим файлом, напишите как исправить ?
Помогите пожалуйста, данная программа берет текст из документа 1.txt ( если документ маленький то всё работает а если большой то выдает...

Исправить ошибку в процедуре
Исправить ошибку в процедуре: Инструкция Select Case в следующей процедуре должна выводить окно сообщения, определяющего меньше ли число,...

Исправить ошибку в процедуре
убейте меня пож, всю ночь потратил на это. Как исправить ту ошибку? Var N,M,i,j,row : integer; myArray: array of integer; ...

Исправить ошибку в процедуре калькулятора
писал калькулятор все правильно,а тут ошибка.помогите исправить procedure TForm2.Button13Click(Sender:TObject); begin...

Ошибка при обращении к хранимой процедуре MS SQL через vba ADODB.Command
Пишет что избыточность параметров не могу не как понять что не так пишу, поправьте пожалуйста. Код хранимой процедуры на сервере MS SQL...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru