Страница 1 из 1

MySQL: параметры процедур.

Добавлено: Вт 01 дек 2015 11:22
fc2000
Здравствуйте!
Столкнулся с такой проблемой: используя следующий код для обращения к процедуре

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

 
  UniStoredProc.StoredProcName:='CHECKID';
  UniStoredProc.PrepareSQL;
  UniStoredProc.Params.CreateParam(ftString,'IN_PARAM',ptInput);
  UniStoredProc.Params.CreateParam(ftString,'OUT_PARAM',ptOutput);
  UniStoredProc.Params.ParamByName('IN_PARAM').AsString:='123abc';
  UniStoredProc.ExecProc;
  Result:= UniStoredProc.ParamByName('OUT_PARAM').AsString;
получаю ошибку вида:
Incorrect number of arguments for PROCEDURE bd.CHEKID; expected 2, got 0

Сразу объясню, для чего параметры создаются вручную: настройки безопасности таковы, что у пользователя есть право только на запуск конкретных процедур и нет права на SELECT для mysql.proc и в результате UniStoredProc.PrepareSQL количество параметров равно нулю.

Вопрос: Я что-то делаю не так или с UniDAC это в принципе невозможно? Такая схема работала с FireDAC для WIndows приложений.

Re: MySQL: параметры процедур.

Добавлено: Ср 02 дек 2015 09:28
fc2000
Отвечу сам: необходимо самому переписывать SQL приводя к виду:
CALL CHECKID(:IN_PARAM, @OUT_PARAM); SELECT @OUT_PARAM AS '@OUT_PARAM'

Re: MySQL: параметры процедур.

Добавлено: Ср 02 дек 2015 10:19
Dimon
Да, действительно, такой запрос необходимо писать для вызова процедуры, потому что MySQL сервер не поддерживает напрямую работу с OUT параметрами.

Re: MySQL: параметры процедур.

Добавлено: Ср 02 дек 2015 12:03
fc2000
хм. вот незадача. несмотря на то, что попытка выполнения процедуры не вызывает ошибки, в результате выполнения получаю null. Что такого еще делает PrepareSQL кроме генерации SQL и создания параметров, чего не делаю я?

Re: MySQL: параметры процедур.

Добавлено: Ср 02 дек 2015 13:26
Alexp
так как после выполнения процедуры выполняется SELECT для получения OUT параметра необходимо обращаться к полю а не к параметру

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

  MyStoredProc1.ParamCheck := False;
  MyStoredProc1.SQL.Text := 'CALL CHECKID(?, @OUT_PARAM); SELECT @OUT_PARAM AS ''OUT_PARAM''';
  MyStoredProc1.Params.CreateParam(ftString,'IN_PARAM',ptInput);
  MyStoredProc1.Params.ParamByName('IN_PARAM').AsString:='123abc';
  MyStoredProc1.ExecProc;
  ShowMessage(MyStoredProc1.FieldByName('OUT_PARAM').AsString);

Re: MySQL: параметры процедур.

Добавлено: Ср 02 дек 2015 13:56
fc2000
Да, действительно, спасибо!
Выходит, что .PrepareSQL в процессе выполнения указывает, что значение нужно вернуть в параметр?
Ибо если я использую .PrepareSQL, то получаю ожидаемое значение параметра.

Re: MySQL: параметры процедур.

Добавлено: Чт 03 дек 2015 11:04
ViktorV
Значение out параметра устанавливается автоматически в корректное значение при выполнении следующих условий:
- свойству StoredProcName присваивается имя хранимой процедуры;
- свойство SQL.Text не устанавливается вручную;
- корректно выполняется метод PrepareSQL, который, если не вызывается вручную, будет автоматически вызван при выполнении метода ExecProc.
Метод PrepareSQL корректно выполнится, только в том случае, когда пользователь обладает правами на выполнение SELECT.
При выполнении кода, приведенного AlexP, получить корректное значение out параметра невозможно, оно будет равное NULL. Поэтому, для получения OUT параметра необходимо обращаться к полю, а не к параметру.

Re: MySQL: параметры процедур.

Добавлено: Пт 22 янв 2016 10:27
fc2000
В продолжение темы.
Ни как не могу разобраться со следующим вопросом, при попытке получить через параметр процедуры изображение из базы данных, столкнулся с тем, что файл, который я получаю из BLOB-поля приходит не полностью. Например при размере файла ~19кб процедура возвращает только ~3 кб.

код, с помощью которого я пытаюсь добиться результата:

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

 
так
  tmpStream:=Proc.CreateBlobStream(tProc.FieldByName('@PICT'),bmRead);
или так
  tmpString:=FESStProc.FieldByName('@AVATAR').AsWideString;
  tmpStream.Write(PString(tmpString),Length(tmpString));
результат одинаково неудовлетворителен :(

Re: MySQL: параметры процедур.

Добавлено: Пн 25 янв 2016 10:25
ViktorV
1. Так как Blob поля, в большинстве случаях, содержат двоичные данные, а не текстовые данные, вам следует использовать метод AsBytes вместо AsWideString. Например:
tmpBytes:=FESStProc.FieldByName('@AVATAR').AsBytes;
tmpStream.Write(tmpBytes[0], Length(tmpBytes));
2. К сожалению, мы не смогли воспроизвести проблему: как при использовании метода TUniStoredProc.CreateBlobStream, так и при использовании метода метода AsBytes мы полностью вычитывали содержимое Blob поля. Для исследования проблемы, пожалуйста, составьте и вышлите нам небольшой пример демонстрирующий проблему, включающий скрипты для создания объектов БД.