Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.11.20;
Скачать: CL | DM;

Вниз

Как узнать если селект в процедуре нашел запись или нет ?   Найти похожие ветки 

 
john   (2005-10-02 18:47) [0]

например

CREATE PROCEDURE LOGIN (
I_LOGIN VARCHAR(25),
I_PASSWORD VARCHAR(255))
RETURNS (
RESULT INTEGER,
O_ERR VARCHAR(255))
AS
DECLARE VARIABLE V_PSWD VARCHAR(255);
BEGIN
result = 0;
SELECT password FROM users
WHERE login = :i_login
INTO v_pswd;

IF (i_password = v_pswd) THEN
 result = 1;
ELSE
 o_err = "Invalid password.";
END

если селект не нашел запись то я хочу возвратить ошибку что нету такого узера.

база - Firebird 1.5


 
msguns ©   (2005-10-02 19:14) [1]

хм.. А зачем вообще это надо серверу ? Пусть прога-"клиент" сама определяет, что делать, если нд пуст. Ведь не исключено, что в некоторых случаях такой результат (нет записей) вполне имеет смысл


 
Deniz ©   (2005-10-03 06:11) [2]

result = 0;
o_err = "";
if (exists(select 1 from users where login=:i_login and password=:i_password)) then
 result = 1;
else
 o_err = "Invalid password or user name.";
suspend;

или

result = 0;
SELECT password FROM users WHERE login = :i_login INTO v_pswd;
IF (v_pswd is null) THEN
 o_err = "Нету такого юзера.";
else
 IF (i_password = v_pswd) THEN
   result = 1;
 ELSE
   o_err = "Invalid password.";
 END
END
suspend;


 
Desdechado ©   (2005-10-03 11:03) [3]

2 Deniz
SUSPEND тут лишний (а по LangRef - вредный), т.к. возвращается не набор данных, а 2 значения в параметрах.

Автору
Я бы поднимал EXCEPTION


 
Sergey13 ©   (2005-10-03 11:16) [4]

А зачем вообще переписывать ЛОГИН? И как отработает эта процедура, если юзер еще не законнектился?


 
john   (2005-10-03 22:49) [5]

Deniz ©   (03.10.05 06:11) [2]

CREATE PROCEDURE LOGIN (
 I_LOGIN VARCHAR(25),
 I_PASSWORD VARCHAR(255))
 RETURNS (
 RESULT INTEGER,
 O_ERR VARCHAR(255))
AS
 DECLARE VARIABLE V_PSWD VARCHAR(255);
BEGIN
 result = 0;
 SELECT password FROM users
 WHERE login = :i_login
 INTO v_pswd;

 IF (v_pswd IS NULL) THEN
   o_err = "Invalid user name";
 ELSE
 IF (i_password = v_pswd) THEN
   result = 1;
 ELSE
   o_err = "Invalid password.";
 SUSPEND;
END


однако не исключено что поле password действительно равно NULL и тогда процедура работает не совсем корректно.
То есть, чтобы сделать это корректно нужно еще сделать запрос на предмет существования такой записи, как вы и предложили...

В оракле это просто:
BEGIN
 SELECT ...
EXCEPTION
 WHEN no_data_found THEN
  ...
END;

Думал, что в Firebird можно сделать что-то аналогичное.


 
Deniz ©   (2005-10-04 07:03) [6]

> Desdechado ©   (03.10.05 11:03) [3]
>
> 2 Deniz
> SUSPEND тут лишний (а по LangRef - вредный), т.к. возвращается не набор данных, а 2 значения в параметрах.

Вредность зависит от варианта вызова.
Если вызывать как select * from login(...) то suspend как раз необходим.
Да и при execute procedure login(...) особых проблем в данном случае не будет.

> john   (03.10.05 22:49) [5]
>однако не исключено что поле password действительно равно NULL и тогда ...


Про это в условии ничего не было(обычно пароли null-ами не бывают). Доработать код не сложно, но если ты не хочешь сам подумать, то ... сожалею. Вариантов может быть много.

DECLARE VARIABLE V_PSWD VARCHAR(255);
declare variable cnt integer;
BEGIN
result = 0;
SELECT password, count(*) FROM users
WHERE login = :i_login
group by password
INTO :v_pswd, :cnt;

IF (cnt is null) THEN
  o_err = "Invalid user name";
ELSE
  IF (i_password = v_pswd) THEN
    result = 1;
  ELSE
    o_err = "Invalid password.";
SUSPEND;
END


 
john   (2005-10-04 09:41) [7]

Deniz ©   (04.10.05 07:03) [6]

> но если ты не хочешь сам подумать, то ... сожалею.

стараюсь по мере возможности :)

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

Но, во всяком случае, теперь понятно как работает single row SELECT в FB.
Так что вопрос закрывается.

С уважением.


 
Desdechado ©   (2005-10-04 10:31) [8]

> Вредность зависит от варианта вызова.
Не вижу смысла вызывать процедуру через SELECT, если она ВСЕГДА возвращает только 2 значения в одной "строке".
А про "execute procedure login(...) особых проблем не будет" - рекомендую еще раз перечитать Language Reference. Там черным по белому написано - ВРЕДНО. Хотя работать будет.


 
Deniz ©   (2005-10-05 08:46) [9]

> Desdechado ©   (04.10.05 10:31) [8]
> > Вредность зависит от варианта вызова.
> Не вижу смысла вызывать процедуру через SELECT, если она ВСЕГДА возвращает только 2 значения в одной "строке".

Читаем внимательно: http://www.ibase.ru/devinfo/ibstp.htm особенно резюме.

стр. 179 (SUSPEND)
...
If the procedure is used as an executable procedure in isql, for example,
EXECUTE PROCEDURE P;
then it will return 1, since the SUSPEND statement will terminate the procedure and return
the current value of r to the calling application. Since SUSPEND should not be used in
executable procedures, EXIT would be used instead, indicating that when the statement
is encountered, the procedure is exited.

Ну перечитал, и что там такого страшного, если мы понимаем как работает suspend? Тем более он (suspend) стоит в конце процедуры.
> Хотя работать будет.
Вот на этом хотелось бы поставить жирную точку в нашем диалоге.


 
Desdechado ©   (2005-10-05 11:37) [10]

кричать не стоит...

А стоит посмотреть на таблицу на стр. 178. И корректно перевести на русский слова "NOT RECOMMENDED" и "SUSPEND should not used". "Should not" - это смягченная форма запрещения.

А оговорки "если мы понимаем как работает suspend" и "если он стоит в конце" весьма кстати. Многие не понимают этого, а просто лепят suspend везде. Вот их и хотелось бы предостеречь.

А приведенная ссылка касается работы отдельных компонентов с отдельными версиями сервера, которые не у автора. И рекомендации обычно пишутся со словом ИМХО.
Добавлю еще от себя: сколько я ни использовать безSUSPENDных процедур, никогда на описанное в статье не нарывался. Хотя работал с IB5.6, IB.6.0, FB1.0, FB1.02, FB1.03, FB1.5х.


 
Seg   (2005-10-05 12:24) [11]

В оракле это просто:
BEGIN
SELECT ...
EXCEPTION
WHEN no_data_found THEN
 ...
END;

Думал, что в Firebird можно сделать что-то аналогичное.


Речь вроде шла об IB6.
Хотя в Оракле действительно многое делается проще.


 
Desdechado ©   (2005-10-05 12:47) [12]

по поводу NO_DATA_FOUND я поступаю так:
1. присваиваю переменной заведомо отсутствующее в таблице значение
2. делаю выборку в переменную
3. если значение не изменилось, то данных не выбрано


 
Seg   (2005-10-05 13:02) [13]

1. присваиваю переменной заведомо отсутствующее в таблице значение

Так ведь данные в таблице меняются и не факт, что кто-то из пользователей не сделает себе пароль, совпадающий с этим значением.


 
Desdechado ©   (2005-10-05 13:12) [14]

это может быть непечатный символ или даже группа таких
если бы пароль не был возможен NULL (что за глупость?), то еще проще


 
Sergey13 ©   (2005-10-05 13:25) [15]

А я опять повторю свой вопрос - нафига переписывать стандартный логин и как это исполнить до подключения к БД?


 
Desdechado ©   (2005-10-05 13:53) [16]

Sergey13 ©   (05.10.05 13:25) [15]
автор вопрос закрыл, так что мы уже не совсем по сабжу толчемся :)

а про логины-пароли: может, у него 2-уровневая проверка, где юзер не знает своего реального логина-пароля к БД, а только некий виртуальный, проверяемый в недоступном ему подключении автоматически программой через процедуру


 
Sergey13 ©   (2005-10-05 13:57) [17]

2 [16] Desdechado ©   (05.10.05 13:53)
>в недоступном ему подключении автоматически
SYSDBA masterkey в прогу зашиты что ли?


 
Desdechado ©   (2005-10-05 15:34) [18]

> SYSDBA masterkey в прогу зашиты что ли?
варианты разные бывают :)
На юзерской машине может какой-нибудь ини хранится, откуда считывается зашифрованный логин-пароль спецюзера с правами на запуск только этой процедуры. Программа запускается, подключается, спрашивает юзера его идентиф. данные и процедурой их проверяет, после чего переконнектится к БД с уже нормальными, но неизвестными юзеру логином-паролем.


 
Deniz ©   (2005-10-06 07:06) [19]

> Sergey13 ©   (05.10.05 13:25) [15]

Desdechado ©   (05.10.05 15:34) [18]
+
вполне может быть что-то более чем двух-звенное, например какой-нибудь web-форум с авторизацией.


 
Deniz ©   (2005-10-06 07:14) [20]

> Desdechado ©
Я конечно согласен, но мне просто не понравилось выражение
Desdechado ©   (03.10.05 11:03) [3]
> SUSPEND тут лишний ...


Как уже меня поправили, все это ИМХО.

Для автора: нужно бы детальнее описывать проблему в будущем, что бы люди могли помочь нормально, а не догадываться об условиях задачи.



Страницы: 1 вся ветка

Текущий архив: 2005.11.20;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.055 c
2-1131111375
San1
2005-11-04 16:36
2005.11.20
Как программно открыть файл PDF. txt, doc и т. д.


2-1130427607
Unknown
2005-10-27 19:40
2005.11.20
Активность программы и SystemTray


2-1131170308
balepa
2005-11-05 08:58
2005.11.20
Как прочитать *.bin


2-1130418128
kyn66
2005-10-27 17:02
2005.11.20
Как удалить компоненты одним махом?


3-1128597127
a80h19
2005-10-06 15:12
2005.11.20
Создание БД через ADO