Использование @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.
Хотя я почти уверен, что версии не имеют значения.
Я не хочу менять версии, поскольку я слишком далеко в проекте.


person Johan    schedule 11.04.2011    source источник
comment
Это действительный MySQL? (Я не использую MySQL, но что-то в IF кажется ... выключенным; MySQL CLI это понимает?)   -  person    schedule 11.04.2011
comment
Да, ошибочно набрал a вместо a; (исправлено сейчас), но кроме этого ДА.   -  person Johan    schedule 11.04.2011
comment
вы пропустили запятую , между AS rank и q.* FROM   -  person ypercubeᵀᴹ    schedule 12.04.2011
comment
Взломал решение, если кто знает что-нибудь более чистое, это было бы здорово. Спасибо всем за то, что нашли время помочь.   -  person Johan    schedule 12.04.2011


Ответы (5)


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

person Jan Doggen    schedule 11.04.2011
comment
Это все равно выдаст ошибку, как только я сделаю запрос активным. Или я что-то упустил. Кстати, меня не беспокоит скорость подготовки запросов, набор данных, с которым работает этот запрос, всегда невелик. - person Johan; 11.04.2011

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

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

person Nicholas Ring    schedule 11.04.2011
comment
Да, пробовал, но код ужасно сложный, и мои патчи, похоже, ничего не делают. - person Johan; 12.04.2011
comment
+1 действительно хорошая идея, если бы я был достаточно умен / терпелив, чтобы вычислить код ZEOS. - person Johan; 12.04.2011

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

person dev-null-dweller    schedule 11.04.2011
comment
Запрос на самом деле на голландском языке, я перевел материал для широкой публики, не понимал, что у меня возникнет конфликт с группой, исправлю код обратно на голландский :-) - person Johan; 11.04.2011
comment
В любом случае проблема заключалась не в этом, просто исходный запрос был длинным, поэтому я сократил его. - person Johan; 11.04.2011

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

person robmil    schedule 11.04.2011
comment
Я думаю, что это из-за ZEOS, без ParamCheck он просто пропускает параметры, если они факты, затем не удается выполнить параметр, но он все равно не проверяет @x: = @y. - person Johan; 12.04.2011

Хорошо, я взломал решение.
Но оно определенно некрасиво, но все же работает (вроде как).

ИЗМЕНИТЬ, этот работает в dbForge-MySQL и Delphi

Сначала я создал в MySQL хранимую функцию «rank», которая хранит значение и / или смещение в @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 и хранимой процедурой работает < / strong> в dbForge, но не работает в Delphi.

person Johan    schedule 11.04.2011
comment
Вы уверены, что проблема была в именах, похожих на @, а не в :=? - person Andriy M; 29.04.2011
comment
Вы неправильно понимаете, проблема в delphi связана с :=, однако проблема между сеансами связана с @variable. - person Johan; 29.04.2011