Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.041 c
14-1130122249
Troyan.DownLoader
2005-10-24 06:50
2005.11.20
Хацкер я или не хацкер !!!


2-1128177159
Giga
2005-10-01 18:32
2005.11.20
SMTP сервер


2-1130797663
Старт
2005-11-01 01:27
2005.11.20
Какую кнопку можно настроить так, чтобы при наведении на неё мыши


3-1128681636
Prohodil Mimo
2005-10-07 14:40
2005.11.20
как использовать ROW_COUNT в FB 1.5.2 ?


1-1130422795
френк
2005-10-27 18:19
2005.11.20
Как отловить закрытие TPopupMenu?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский