Vожно ли передать в UDF указатель (Pointer)?

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

Vожно ли передать в UDF указатель (Pointer)?

Сообщение Zhur » 20 мар 2006, 08:58

Добрый день.
Вот, создал класс для оптимизации выборки данных. По сути, в нем хранятся сами условия (например: A10-A19.9; B05; C02-C02.9 или более простое: A10-A19.9) и генерится соответствующее условие WHERE для запроса. Также в нем имеется и метод сравнения сложных выражений (таких как вышеуказанное) и конкретного значения (Например, если значение = A11.1 - True).
Имеется отдельная функция UDF (для обработки сложных условий) . в которой на данном этапе приходится создавать экземпляр такого класса, что бы проверить истинность для конкретной записи. Но, сами понимаете, что тут будет NATURAL, да еще какжый раз создается экземпляр этого класса (в функции UDF).
Вот и хотелось бы создать экземпляр такого класса заранее, а в функцию UDFпередавать указатель на него.
Возможно ли это?
Заранее благодарен.

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

Сообщение kdv » 20 мар 2006, 10:23

Вот и хотелось бы создать экземпляр такого класса заранее, а в функцию UDF передавать указатель на него.
ты сам понял что написал? где класс, и где udf? :)

Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

Сообщение Zhur » 20 мар 2006, 11:13

Извиняюсь, если плохо написал...
В общем-то вопрос простой, можно ли динамически составить запрос, что бы сервер передавал в UDF указатель?
Если непонятно "зачем", привожу пример:
В упрощенном варианте листинг примерно такой:
-Класс:

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

TExpr = class
  private
    FText: String;
    FList: TStringList;
  public
    property Text: String read FText write SetText;
    property List: TStringList read FList write SetList;
    function Verify(const Value: ShortString): Boolean;
    function GetSQLWhere(const Field: ShortString): String;
  end;

function TExpr.GetSQLWhere(const Field: ShortString): String;
begin
    Result := 'UDF_ExprVerify('+Field+','''+FText+''')>0';
end;
-Сейчас UDF выглядит так:

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

function UDF_ExprVerify(Value: PChar; Expr: PChar): Integer; cdecl; export;
var
  Expr: TExpr;
begin
  Expr := TExpr.Create;
  Expr.Text := String(Expr);
  if Expr.Verify(String(MKB)) then Result := 1
  else Result := 0;
  Expr.Free;
end;
Осн. программа:
Тут имеется спенциальный компонент ExprEdit: TExprEdit.
Имеем:

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

...
Query.SQL.Add('Select...');
Query.SQL.Add('where '+ExprEdit.Expr.GetSQLWhere('MYFIELD'));
...
Query.SQL.Open;
А проблема в том, что в UDF создается экэемпляр класса TExpr.
А хотелось бы что-то вроде такого:
function UDF_ExprVerify(Value: PChar; PExpr: Pointer): Integer; cdecl; export;

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

var Expr: TExpr;
begin
  Expr := TExpr(PExpr);
  if Expr.Verify(String(MKB)) then Result := 1
  else Result := 0;
end;
Тогда будет побыстрее.
PS. Что-то я не могу понять, как использовать Тег CODE, за что извиняюсь.

Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

Сообщение Zhur » 20 мар 2006, 14:37

Короче... можно передавать указатель... или это невозможно?

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

Сообщение Merlin » 20 мар 2006, 14:58

Что ты занимаешься глубокой проктологией - это видно невооружённым глазом. А вот пачиму... Фанат IB6.0 или релизные ноты не читаем из религиозных убеждений?

Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

Сообщение Zhur » 20 мар 2006, 15:08

Merlin писал(а):Что ты занимаешься глубокой проктологией - это видно невооружённым глазом. А вот пачиму... Фанат IB6.0 или релизные ноты не читаем из религиозных убеждений?
Ниче не понимаю... почему "фанат" и про какие ноты?
Я вообще то на SQL тока учусь... а так на фоксе работал... в больнице... обычной бедненькой больнице... а учуся потому что сам стараюсь сделать у себя в больнице что-то хорошее... Разве это плохо?
Так что приходится иногда (а может и всегда) глупые вопросы задавать.
В данном случае хочу сделать стандартную вещь для быстрого поиска записей по небольшим справочникам. Думаю, кстати, что идея хорошая.

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

Сообщение kdv » 20 мар 2006, 15:36

у тебя класс на клиенте, а udf - на сервере. О каком вообще "указателе" может идти речь???

Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

Сообщение Zhur » 20 мар 2006, 15:47

kdv писал(а):у тебя класс на клиенте, а udf - на сервере. О каком вообще "указателе" может идти речь???
Так ведь у меня и UDF.DLL, и клиентская прога компилится из одного и того же UNITа. Так что, если бы в UDF-ку пришел указатель... то она бы знала что это за указатель и с чем его едят... и вернула бы то что нужно... не создавая свой экземпляр класса.

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

Сообщение Merlin » 20 мар 2006, 15:49

Ну вот почему, почему все неофиты поголовно, как только возникает нужда почесать гланды, начинают искать пути к ним исключительно и только через задницу? Моя голова никак не может этого понять.

1. Динамические запросы хомы сапиенсы стараются делать с клиента. Причём по возможности стараются от динамики уйти и прийти к параметризованной статике. Стремление затолкать все динамические запросы, особенно многократно используемые, в SP, чтоб они там препарировались при каждом обращении - это _уже_ проктология, потому что это больше нагружает сервер, чем однократно препарированный параметризованный запрос с клиента. Не говоря уж о применении для этого UDF.

2. Существуют таки ситуации, когда потери на препаре в динамике в SP меньше чем потери на трафике при динамике в клиенте. Редко, но существуют. В таких случаях умеющие читать доку, в том числе и Release Notes к используемой версии сервера, не изобретают лисапеды на квадратных колёсах, а применют в SP Execute Statement.

Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

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

Прочитав недавно, как один человек на Вас обиделся, и как Вы его утешали, я понял, что обижаться нам, ниофитам, не стоит.
И все же, честно говоря, я немного не понимаю Вашего лексикона. Как у нас говорят "а теперь по русски, пожалуйста".
Конечно же я читаю все, что можно. Просто не все в голове сразу укладывается.
В любом случае спасибо... я кое-что понял. Действительно...UDF тут не при чем. Сгенерю запрос на клиенте, если так можно:
where FIELD between A and B
or FIELD between C and D
or FIELD=E
or FIELD between F and G
Ура... получилось... Здорово... и работает быстро.
Спасибо Merlin! Надоумил таки.

Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

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

Я теперь прямо в классе выражение Where генерю.
Это все от фокса привычка осталась...
В общем, нет слов.

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

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

Так ведь у меня и UDF.DLL, и клиентская прога компилится из одного и того же UNITа. Так что, если бы в UDF-ку пришел указатель... то она бы знала что это за указатель и с чем его едят... и вернула бы то что нужно... не создавая свой экземпляр класса.
ужас какой. объясняю популярно. Указатель на экземпляр - это указатель на кусок памяти. Который на клиенте. Так? Теперь мы передаем этот указатель в UDF, пусть в виде integer. UDF на сервере, так? Что сервер будет делать на сервере с указателем на кусок памяти, который находится где-то там на клиенте???
ну а про компиляцию из одного юнита - это тоже мощно. предлагаю решить задачу - каким образом кусок кода в dll связан с указателем на кусок памяти в совсем другом месте. Это как взять два exe. в одном создать экземпляр класса, и указатель на него передать в другой exe. Работать не будет.

Zhur
Сообщения: 125
Зарегистрирован: 01 мар 2006, 18:17

Сообщение Zhur » 21 мар 2006, 08:15

Спасибо... я уже отказался от своей затеи... спасибо Merlin помог.
Сам удивляюсь... что раньше не догадался... Просто я ранньше тока с фоксом работал... а на нем большие выражения - низя. Вот и привык извращаться.
Еще раз спасибо.

Ответить