Использование @variables:= в запросе Delphi не работает

У меня следующая проблема.

ZQuery1.SQL.Text:= 
  ' SELECT                                                  '+
  '   IF(q.rank2 = 1, @rank:= 1, @rank:= @rank + 1) AS rank '+
  '   ,q.* FROM (                                            '+
  '   SELECT groep.id - MinGroepId(groep.id) AS rank2       '+
  '     ,groep.otherfields                                  '+
  '   FROM groep                                            '+
  '   ORDER BY rank2 ) q;                                   ';
ZQuery.Open;

Когда я запускаю этот код, я получаю исключение Incorrect token followed by ":" в ZQuery1.
Как это исправить? Мне нужно использовать Delphi, потому что я не могу поместить этот выбор в процедуру MySQL.
Zeos 6 не поддерживает процедуры MySQL, которые возвращают набор результатов.

PS
Я использую Delphi 2007 и MySQL 5.1 с ZEOS 6.6.6.
Хотя я уверен, что версии не имеют значения.
Я не хочу переключать версии, потому что я слишком далеко в проекте.

5 ответов

Решение

ОК, я взломал решение.
Но это, конечно, некрасиво, все же это работает (Сорта).

РЕДАКТИРОВАТЬ, этот работает в dbForge-MySQL и Delphi

Сначала я создал хранимую функцию 'rating' в MySQL, которая хранит значение и / или смещение в @rank.

CREATE DEFINER = 'root'@'localhost'
FUNCTION MyDatabase.Ranking(NewRank INT, Addition INT)
  RETURNS int(11)
BEGIN
  IF NOT(NewRank IS NULL) THEN SET @rank:= NewRank; END IF;
  IF NOT(Addition IS NULL) THEN SET @rank:= @rank + Addition; END IF;
  RETURN @rank;   
END

Затем я изменил ZQuery1, чтобы прочитать что-то вроде:

select ranking(null,1) as rank
  ,groep.*
  from groep
join (select ranking(0,null)) r

Это работает, и полный сложный код в Delphi также работает.(-_-')
Очередной триумф над злыми машинами

Итак, подведем итоги.
@varname сохраняется в хранимой процедуре (разумеется, внутри одного соединения).
Обмен @varname между оператором select и хранимой процедурой работает в dbForge, но не работает в Delphi.

Это не может быть сделано, вы можете только параметризовать значение. Лучшее, что вы можете сделать, это SQL.Text:= StringReplace(), но вы теряете скорость подготовки запросов.

MySQL имеет возможность иметь пользовательские переменные (основанные на сеансах), которые ссылаются на @ (поэтому я не хочу сказать, что LaKraven немного не в порядке). У меня была такая же проблема с Dac для MySQL (http://www.microolap.com/products/connectivity/mysqldac/) на работе. Они исправили, установив специальную проверку, чтобы увидеть, был ли символ после ':' равен '=', и если это так, замена параметров не произошла.

Я не очень много знаю о компонентах Zeos, поэтому единственное, что я могу предложить, - это проследить путь выполнения и посмотреть, где происходит исключение, и пропатчить код для обработки последовательности символов ':='

Попробуйте установить TZQuery.ParamCheck в False. Это отключит автоматическое создание параметров, когда ":" является маркером параметра.

Я не знаю, так ли это здесь, но у вас есть ошибки в вашем SQL: точка с запятой в IF следует заменить на запятую, после запятой отсутствует AS rank а также group зарезервированное слово, поэтому при использовании в качестве имени таблицы оно должно быть заключено в `` .

Другие вопросы по тегам