Вывод данных в процедурах

ЧАстые Вопросы и Ответы

Модераторы: kdv, CyberMax

Ответить
Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Вывод данных в процедурах

Сообщение Hadroran » 13 фев 2006, 09:06

Мастера, помогите.
Создал процедуру, которая в таблице просматривает, количество какого товара на складе меньше минимального запаса. После формирования сообщения возвращаю данные командой suspend. Однако после прохода всех записей в программе пытаюсь организовать цикл

Код: Выделить всё

  DM.IBSQL.Close;
  DM.IBSQL.SQL.Clear;
  DM.IBSQL.SQL.Add('select RESULT_TEXT_MIN from CREATE_ALARM_LIST(10,5)');
  DM.IBSQL.ExecQuery;
   repeat
      [i][b]sss:=DM.IBSQL.Fields[tmp].AsString;[/b][/i]
      tmp1:=pos(',',sss);
      ListItem:=FormGlava.AlarmList.Items.Add;
      ListItem.Caption:=copy(sss,1,tmp1-1);
      delete(sss,1,tmp1);
      ListItem.SubItems.DelimitedText:=sss;
      DM.IBSQL.Next;
      inc(tmp);
   until
      tmp>=DM.IBSQL.RecordCount;
  DM.IBSQL.Close;
Однако на втором круге на выделенной строке возникает ошибка, что не найден Fields[1].
Может что-нибудь не так делаю.
И еще вопрос, как в хранимой процедуре организовать запись в переменную типа BLOB и затем вывести данные в ListView или Memo?
Спасибо.

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 13 фев 2006, 10:13

1. Это что, вопрос для FAQ ? :evil:
2. Номер поля от кол-ва обработанных записей отличаем ?

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 13 фев 2006, 10:16

Ё-блин. Теперь отличаем, а как быть?

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 13 фев 2006, 10:29

Hadroran писал(а):Теперь отличаем, а как быть?
Даже не знаю - очень сложный для меня вопрос

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 17 фев 2006, 11:23

hvlad писал(а):Даже не знаю - очень сложный для меня вопрос
:evil:

А ответ все-таки нашел. Правда не такой как хотелось бы но подойдет.

Код: Выделить всё

            alarm_text='Количество товара "'||tname||'" на складе меньше минимального запаса';
            alarm_status='Тревога';
            insert into alarmlist (
                   dates,
                   message_text,
                   status_text,
                   stroka
            )
            values (
                   "now",
                   :alarm_text,
                   :alarm_status,
                   :id_source
            );

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 фев 2006, 12:46

двойные кавычки в третьем диалекте используются для "обрамления" регистро-чувствительных имен объектов (если это нужно). Так что "now" смени пока не поздно.

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 01 мар 2006, 17:07

kdv писал(а):двойные кавычки в третьем диалекте используются для "обрамления" регистро-чувствительных имен объектов (если это нужно). Так что "now" смени пока не поздно.
Не, диалект 1. Проблем пока нет.

kdv:
Если ты с Delphi работаешь, объясни танкисту :D , вот перечитал все топики по коннекту к базе через логин, пароль и роль. Единственное понятное моему мозгу был код
SELECT RDB$Relation_Name FROM RDB$User_Privileges WHERE RDB$User = :UserName;
но танкист применить его не может. Глянь плиз на мое творчество в Delphi.

Код: Выделить всё

  IBDatabase.Connected:=false;
  IBDatabase.Params.Clear;
  IBDatabase.Params.Append('user_name='+FormGlava.LoginUs);
  IBDatabase.Params.Append('password='+FormGlava.PassUs);  IBDatabase.DatabaseName:=FormGlava.ServerName+':'+FormGlava.BaseName;
    try
     IBDatabase.Connected:=true;
    except
     exit;
    end;
  IBTransaction.Active:=true;
  IBSQL.SQL.Clear;
  IBSQL.SQL.Add('SELECT RDB$Relation_Name FROM RDB$User_Privileges WHERE RDB$User = :UserName;');
  IBSQL.ExecQuery;
  Role:=IBSQL.Fields[0].AsVariant;
  IBSQL.Close;
В переменной Role полная пурга. :shock:
Помоги реализовать коннект к базе с указанием роли.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 01 мар 2006, 17:29

Не, диалект 1. Проблем пока нет.
тебе нужны проблемы в дальнейшем?
SELECT RDB$Relation_Name FROM RDB$User_Privileges WHERE RDB$User = :UserName

В переменной Role полная пурга.
а то. если запрос-пурга, то и результат будет пурга. :)
ты бы глянул в rdb$user_provileges, и увидел, что включение пользователя в роль - это специальная запись, где rdb$privilege стоит в значении 'M' (membership), если юзер включен в роль (grant rolename to username). Соответственно запрос должен быть:

Код: Выделить всё

select rdb$relation_name 
from rdb$user_privileges
where rdb$privilege = 'M' and rdb$user = :username;
если юзер включен в несколько ролей, то и записей будет несколько.
Role:=IBSQL.Fields[0].AsVariant;
так трудно написать asString? К чему этот выпендреж с вариантом? Или что, роль может быть числом или датой? Или переменная role в приложении определена как variant? :)

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 01 мар 2006, 17:44

Поменял код:

Код: Выделить всё

  IBSQL.SQL.Clear;
  IBSQL.SQL.Add('select rdb$relation_name from rdb$user_privileges where rdb$privilege = ''M'' and rdb$user = :username;');
  IBSQL.ExecQuery;
  Role:=IBSQL.Fields[0].AsString;
  IBSQL.Close;
Значение переменной Role не поменялись. Опять пурга :shock:
А значение пурги такое - #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 01 мар 2006, 18:21

чудо - ты этот запрос сначала выполни хотя бы в IBExpert. Он у тебя хоть одну запись выдает? Ты пользователя в роль включил???

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 01 мар 2006, 18:25

Имхо там и ролей-то в базе нет...

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 01 мар 2006, 18:30

пользователя чудо в роль включило, в IBExpert запрос выполнило, ответ получило - ADMINISTRATOR

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 01 мар 2006, 18:39

Hadroran писал(а):пользователя чудо в роль включило, в IBExpert запрос выполнило, ответ получило - ADMINISTRATOR
Эх, если бы оно ещё догадалось в :username чего-нить засунуть перед ExecQuery, цены бы ему не было ;)

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 01 мар 2006, 18:50

Это процедура, право на выполнение есть

Код: Выделить всё

CREATE PROCEDURE GET_ROLE (
    USERNAME VARCHAR(31))
RETURNS (
    RDB$RELATION_NAME CHAR(31))
AS
BEGIN
  FOR
    select rdb$relation_name 
    from rdb$user_privileges 
    where rdb$privilege = 'M' and rdb$user = :username
    INTO :RDB$RELATION_NAME
  DO
  BEGIN
    SUSPEND;
  END
END
Это код программы

Код: Выделить всё

  IBDatabase.Connected:=false;
  IBDatabase.Params.Clear;
  IBDatabase.Params.Append('user_name='+FormGlava.LoginUs);
  IBDatabase.Params.Append('password='+FormGlava.PassUs);
  IBDatabase.DatabaseName:=FormGlava.ServerName+':'+FormGlava.BaseName;
    try
     IBDatabase.Connected:=true;
    except
     exit;
    end;
  IBTransaction.Active:=true;
  IBSQL.Close;
  IBSQL.SQL.Clear;
  IBSQL.SQL.Add('select RDB$RELATION_NAME from GET_ROLE('+FormGlava.LoginUs+')');
  IBSQL.ExecQuery;
  Role:=IBSQL.Fields[0].AsString;
  IBSQL.Close;
Так? :?

PS: плиз поиметь терпение

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 01 мар 2006, 19:41

так. потом реконнект уже с добавлением к параметрам логина роли.

и еще. вот это
IBTransaction.Active:=true;
настоятельно НЕ рекомендую.
Писать надо IBTransaction.StartTransaction;
иначе возникнет соблазн для завершения транзакции вызвать
IBTransaction.Active:=False :)
да и в исходниках старты транзакций в результате будет легче искать.

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 02 мар 2006, 09:09

kdv писал(а):так. потом реконнект уже с добавлением к параметрам логина роли.
Доброе утро.

-> kdv
Вот тут-то уменя и грабли.
После этого не знаю куда присваивать полученное значение роли. :cry:

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 02 мар 2006, 09:30

Парень, никакое терпение нельзя иметь бесконечно...
Тебе же сказали: в параметры логина. Т.е. TIBDatabase.Params. Название параметра sql_role (раз уж тебе исползовать F1 религия не позволяет).

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 02 мар 2006, 09:51

Dimitry Sibiryakov писал(а):TIBDatabase.Params. Название параметра sql_role
Мля, во я олень..... :lol:

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 02 мар 2006, 16:16

И все-таки если использовать этот вариант при исполнении данного запроса выводится ошибка "типа неизвестный пользователь". Ессссстественно вместо :username вводим пользователя прописанного в базе. Если же данный запрос написан в процедуре

Код: Выделить всё

BEGIN
 FOR
   select rdb$relation_name 
   from rdb$user_privileges 
   where rdb$privilege = 'M' and rdb$user = :username
   INTO :RDB$RELATION_NAME
 DO
 BEGIN
   SUSPEND;
 END 
END
и права на ее выполнения даны данному пользователю, то результат RDB$RELATION_NAME равняется NULL, хотя при отладке процедуры на сервере все получается.

Hadroran
Сообщения: 39
Зарегистрирован: 22 фев 2005, 10:23

Сообщение Hadroran » 02 мар 2006, 16:20

Все навиг, вопрос снимаю. Опять я олень. :twisted:
Имя пользователя взять в кавычки одинарные :lol:

Ответить