SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 15.05.2016 09:30:15

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Ошибка синтаксиса

Добрый день, опять MySQL вводит меня в тупик, или я уже сам просто крайне невнимателен.

Хочу реализовать процедуру на добавление нового договора:

create procedure SigningContract(new_id int, new_sum int, new_begin date, new_individ int,
new_comp int, new_agent int, new_object int, new_categ int)
begin
declare check1 int;
declare check1plus int;
set check1 = (select max(id_contract) from insurance_contract);
set check1plus = check1++;

if (select count(*) from insurance_contract where id_contract = new_id) != 0 then new_id = check1plus;
else if (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
else if (select count(*) from company where id_company = new_comp) = 0 then signal sqlstate '45000' set message_text = 'Такой компании не существует';
else if (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
else if (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
else if (select count(*) from insurance_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
end if;
end if;
end if;
end if;
end if;
end if;
insert into insurance_contract values(new_id, new_sum, new_begin, AddPeriod(new_begin), new_individ, new_comp, new_agent, new_object, new_categ);
end

Добавление со все возможными проверками (правильность ввода id, существования клиента и т. д.), также есть функция AddPeriod(new_begin), возвращающая окончание срока договора.
Но почему-то эта процедура не компилируется, выдавая ошибку синтаксиса рядом с первой проверкой IF. Неужели я умудрился допустить ошибку в таком месте?

Неактивен

 

#2 15.05.2016 09:46:57

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

Впервые слышу об операторе ++ (check1++) в MySQL!

Неактивен

 

#3 15.05.2016 09:51:45

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

Вы думаете это не будет работать? Просто на set check1plus = check1 + 1 тоже ругался

Неактивен

 

#4 15.05.2016 09:56:00

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

думаю не будет.
Кроме того
new_id = check1plus; нужно SET new_id = check1plus;
else if нужно elseif

Отредактированно klow (15.05.2016 10:00:14)

Неактивен

 

#5 15.05.2016 10:00:21

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

klow написал:

думаю не будет.
Кроме того ELSE IF! http://dev.mysql.com/doc/refman/5.7/en/ … unction_if
рекомендую использовать CASE http://dev.mysql.com/doc/refman/5.7/en/ … rator_case

Хорошо, case - вероятно хорошее решение, но мне бы хотелось всё-таки ещё разобраться  у себя с IF, что не нравится в моей конструкции

Неактивен

 

#6 15.05.2016 10:01:06

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

Ovenvan написал:

klow написал:

думаю не будет.
Кроме того ELSE IF! http://dev.mysql.com/doc/refman/5.7/en/ … unction_if
рекомендую использовать CASE http://dev.mysql.com/doc/refman/5.7/en/ … rator_case

Хорошо, case - вероятно хорошее решение, но мне бы хотелось всё-таки ещё разобраться  у себя с IF, что не нравится в моей конструкции

это я немного погорячился. Исправил. см. мое предыдущее сообщение

Отредактированно klow (15.05.2016 10:02:44)

Неактивен

 

#7 15.05.2016 10:05:02

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

Действительно нельзя использовать else if? хм.. не знал
Попробовал исправить по Вашим советам:

create procedure SigningContract(new_id int, new_sum int, new_begin date, new_individ int,
new_comp int, new_agent int, new_object int, new_categ int)
begin
declare check1 int;
declare check1plus int;
set check1 = (select max(id_contract) from insurance_contract);
set check1plus = check1++;

if (select count(*) from insurance_contract where id_contract = new_id) != 0 then set new_id = check1plus;
elseif (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
elseif (select count(*) from company where id_company = new_comp) = 0 then signal sqlstate '45000' set message_text = 'Такой компании не существует';
elseif (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
elseif (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
elseif (select count(*) from insurance_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
else insert into insurance_contract values(new_id, new_sum, new_begin, AddPeriod(new_begin), new_individ, new_comp, new_agent, new_object, new_categ);
end if;
end if;
end if;
end if;
end if;
end if;
end

Ошибка в том же первом условии(

Неактивен

 

#8 15.05.2016 10:06:41

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

set check1plus = check1++;
Нужно
set check1plus = check1+1;
Кроме того, нужен только один end if;

Неактивен

 

#9 15.05.2016 10:07:49

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

create procedure SigningContract(new_id int, new_sum int, new_begin date, new_individ int,
new_comp int, new_agent int, new_object int, new_categ int)
begin
declare check1 int;
declare check1plus int;
set check1 = (select max(id_contract) from insurance_contract);
set check1plus = check1+1;

if (select count(*) from insurance_contract where id_contract = new_id) != 0 then set new_id = check1plus;
elseif (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
elseif (select count(*) from company where id_company = new_comp) = 0 then signal sqlstate '45000' set message_text = 'Такой компании не существует';
elseif (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
elseif (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
elseif (select count(*) from insurance_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
else insert into insurance_contract values(new_id, new_sum, new_begin, AddPeriod(new_begin), new_individ, new_comp, new_agent, new_object, new_categ);
end if;
end

Неактивен

 

#10 15.05.2016 10:15:30

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

Можно еще немного упростить

...
declare check1 int;
-- declare check1plus int;
set check1 = (select max(id_contract) from insurance_contract);
-- set check1plus = check1+1;

if (select count(*) from insurance_contract where id_contract = new_id) != 0 then set new_id = check1 + 1;
...

Отредактированно klow (15.05.2016 10:15:57)

Неактивен

 

#11 15.05.2016 11:06:09

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

Благодарю Вас, удалил лишние END IF, всё скомпилировалось.

Но теперь возникла проблема алгоритмическая, в таблице контрактов у меня в полях Individual и Company могут быть значения null, в зависимости с кем контракт, а при моей проверке постоянно выводит "Такого ... не существует ", как работать с null проверкой?

Например с таким вызовом: call SigningContract(11, 500, '2016-05-15', 11,
null, 7, 11, 5)
Ошибка не существования клиента, а он есть

Отредактированно Ovenvan (15.05.2016 11:11:21)

Неактивен

 

#12 15.05.2016 11:10:18

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Ошибка синтаксиса

is null

Неактивен

 

#13 15.05.2016 11:17:04

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

Хм... я чего-то совсем не понимаю, вызов процедуры выполняется, но в таблицу ничего не добавляется

create procedure SigningContract(new_id int, new_sum int, new_begin date, new_individ int,
new_comp int, new_agent int, new_object int, new_categ int)
begin
declare check1 int;
set check1 = (select max(id_contract) from insurance_contract);
if (select count(*) from insurance_contract where id_contract = new_id) = 0 then set new_id = check1 + 1;
elseif (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
elseif (select count(*) from company where id_company = new_comp) = 0 then signal sqlstate '45000' set message_text = 'Такой компании не существует';
elseif (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
elseif (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
elseif (select count(*) from insurance_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
else insert into insurance_contract(id_contract, sum_insured, beginning, ending, Individual, Company,  Agent,  Object, Category)
values(new_id, new_sum, new_begin, AddPeriod(new_begin), new_individ, new_comp, new_agent, new_object, new_categ);
end if;
end


call SigningContract(11, 500, '2016-05-15', 11, null, 7, 11, 5)

Отредактированно Ovenvan (15.05.2016 11:17:26)

Неактивен

 

#14 15.05.2016 11:27:15

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Ошибка синтаксиса

if (select count(*) from insurance_contract where id_contract = new_id) = 0 then set new_id = check1 + 1; -- присвоили значение
...
end if;
end -- закончили процедуру. Почему что-то должно добавиться?

Неактивен

 

#15 15.05.2016 11:32:16

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

Посмотрите на условия. Например, смысла в set new_id = check1 + 1 первом IF вообще никакого нет. Оно все равно не будет использовано.
Возможно

if (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
elseif (select count(*) from company where id_company = new_comp) = 0 then signal sqlstate '45000' set message_text = 'Такой компании не существует';
elseif (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
elseif (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
elseif (select count(*) from insurance_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
else
  if (select count(*) from insurance_contract where id_contract = new_id) = 0 then set new_id = check1 + 1 end if;
  insert into insurance_contract(id_contract, sum_insured, beginning, ending, Individual, Company,  Agent,  Object, Category)
  values(new_id, new_sum, new_begin, AddPeriod(new_begin), new_individ, new_comp, new_agent, new_object, new_categ);
end if;


Не успел. smile

Отредактированно klow (15.05.2016 11:33:19)

Неактивен

 

#16 15.05.2016 11:42:59

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Ошибка синтаксиса

klow написал:

Не успел. smile

зато я только указал на проблему, а вы и решение предложили

Неактивен

 

#17 15.05.2016 12:55:16

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

То есть процедура должна иметь вот такой вид?


create procedure SigningContract(new_id int, new_sum int, new_begin date, new_individ int,
new_comp int, new_agent int, new_object int, new_categ int)
begin
declare check1 int;
declare periodplus int;
set check1 = (select max(id_contract) from insurance_contract);
set periodplus = (select Period from guide_services where id_guide = (select Category from insurance_contract where id_contract = new_id));
if (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
elseif (select count(*) from company where id_company = new_comp) = 0 then signal sqlstate '45000' set message_text = 'Такой компании не существует';
elseif (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
elseif (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
elseif (select count(*) from insurance_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
else
  if (select count(*) from insurance_contract where id_contract = new_id) = 0 then set new_id = check1 + 1 end if;
  insert into insurance_contract(id_contract, Sum_insured, Beginning, Ending, Individual, Company,  Agent,  Object, Category)
  values(new_id, new_sum, new_begin, AddPeriod(new_begin, periodplus), new_individ, new_comp, new_agent, new_object, new_categ);
end if;
end


Просто не будет ложью, если скажу, что запутался, вроде всё понял, а ошибку синтаксиса всё рано выдаёт

Отредактированно Ovenvan (15.05.2016 12:57:06)

Неактивен

 

#18 15.05.2016 13:04:37

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 411

Re: Ошибка синтаксиса

Мне сложно судить не зная деталей задачи, но думаю нужно немного подправить

create procedure SigningContract(new_id int, new_sum int, new_begin date, new_individ int,
new_comp int, new_agent int, new_object int, new_categ int)
begin
declare check1 int;
declare periodplus int;
set check1 = (select max(id_contract) from insurance_contract);

if (select count(*) from insurance_contract where id_contract = new_id) = 0 then set new_id = check1 + 1; end if; -- Перенес и исправил

set periodplus = (select Period from guide_services where id_guide = (select Category from insurance_contract where id_contract = new_id));
if (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
elseif (select count(*) from company where id_company = new_comp) = 0 then signal sqlstate '45000' set message_text = 'Такой компании не существует';
elseif (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
elseif (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
elseif (select count(*) from insurance_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
else
--  if (select count(*) from insurance_contract where id_contract = new_id) = 0 then set new_id = check1 + 1 end if;
  insert into insurance_contract(id_contract, Sum_insured, Beginning, Ending, Individual, Company,  Agent,  Object, Category)
  values(new_id, new_sum, new_begin, AddPeriod(new_begin, periodplus), new_individ, new_comp, new_agent, new_object, new_categ);
end if;
end

Отредактированно klow (15.05.2016 13:06:20)

Неактивен

 

#19 15.05.2016 21:59:58

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

Спасибо Вам всем за помощь, немного переписал процедуру, теперь не знаю как решить ещё одну проблемку.

create procedure SigningContractClient(new_id int, new_sum int, new_begin date, new_individ int, new_agent int, new_object int, new_categ int)
begin
declare check1 int;
declare periodplus int;
declare ending date;
set check1 = (select max(id_contract) from insurance_contract);
set ending = AddPeriod(new_begin, periodplus);
if (select count(*) from insurance_contract where id_contract = new_id) = 0 then set new_id = check1 + 1; end if;
if (select count(*) from individual where id_individual = new_individ) = 0 then signal sqlstate '45000' set message_text = 'Такого клиента не существует';
elseif (select count(*) from insurance_agent where id_agent = new_agent) = 0 then signal sqlstate '45000' set message_text = 'Такого агента в нашем агентстве нет';
elseif (select count(*) from object_insurance where id_object = new_object) = 0 then signal sqlstate '45000' set message_text = 'Такой объект страхования не зарегистрирован';
elseif (select count(*) from guide_services where id_guide = new_categ) = 0 then signal sqlstate '45000' set message_text = 'Такая услуга невозможна';
else
insert into insurance_contract(id_contract, Sum_insured, Beginning, Ending, Individual, Company,  Agent,  Object, Category)
values(new_id, new_sum, new_begin, ending, new_individ, null, new_agent, new_object, new_categ);
end if;
set periodplus = (select Period from guide_services where id_guide = (select Category from insurance_contract where id_contract = new_id));
set ending = AddPeriod(new_begin, periodplus);
if (select Ending from insurance_contract where id_contract = new_id) is null then update insurance_contract set Ending = ending where id_contract = new_id; end if;
end


Есть функция AddPeriod(new_begin, periodplus), на входе у неё дата и количество лет для увеличение даты, на выходе новая увеличенная дата. Только вместо даты он вставляет null

Неактивен

 

#20 15.05.2016 22:05:32

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Ошибка синтаксиса

А зачем функция?

set ending = new_begin + INTERVAL periodplus YEAR;

Неактивен

 

#21 15.05.2016 22:12:21

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

rgbeast написал:

А зачем функция?

set ending = new_begin + INTERVAL periodplus YEAR;

Понимаю Вашу заинтересованность, просто уже придумать что-то из функций более толковое не смог. Кстати, функция это и делает


create function AddPeriod(FirstDate date, newperiod int)
returns date
begin
declare newdate date;
set newdate = (select adddate(FirstDate, interval newperiod year));
return(newdate);
end

Неактивен

 

#22 15.05.2016 22:15:33

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Ошибка синтаксиса

У Вас первый вызов 

set ending = AddPeriod(new_begin, periodplus);
происходит до того, как переменной periodplus присвоено какое-либо значение. Поэтому результат NULL

Неактивен

 

#23 15.05.2016 22:18:31

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

rgbeast написал:

У Вас первый вызов 

set ending = AddPeriod(new_begin, periodplus);
происходит до того, как переменной periodplus присвоено какое-либо значение. Поэтому результат NULL

Да, соглашусь, и поэтому у меня поле Ending может быть null. Возможно ли в этой процедуре после INSERT перезаписать это значение?

Я вот попробовал в конце

set periodplus = (select Period from guide_services where id_guide = (select Category from insurance_contract where id_contract = new_id));
set ending = AddPeriod(new_begin, periodplus);
if (select Ending from insurance_contract where id_contract = new_id) is null then update insurance_contract set Ending = ending where id_contract = new_id; end if;

Но боюсь это уж слишком тупо)

Неактивен

 

#24 15.05.2016 22:26:12

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Ошибка синтаксиса

Отлаживайте вручную по шагам.
В guide_services есть необходимая запись?
Что попадает в переменную periodplus?

Неактивен

 

#25 15.05.2016 22:34:37

Ovenvan
Завсегдатай
Зарегистрирован: 13.05.2016
Сообщений: 27

Re: Ошибка синтаксиса

rgbeast написал:

Отлаживайте вручную по шагам.
В guide_services есть необходимая запись?
Что попадает в переменную periodplus?

Необходимая запись есть.
В guide_services содержится наименование услуги и её период страхования  в виде обычного числа (количество лет), а в periodplus попадает как раз это число, которое используется в новом контракте.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson