Переменная присваивания mysql: как заставить порядок присваивания? - PullRequest
2 голосов
/ 07 февраля 2011

Из-за того, что mysql является декларативным языком, я не могу найти способ форсировать порядок присваивания переменных.

Возьмите этот запрос:

SET @v1=0;
SET @v2=0;

SELECT @v1, @v2 
FROM MyTable table 
WHERE (@v1:=@v2) is not null 
  AND (@v2:=2) is not null;

Результат:

@v1 | @v2
---------
 2  |  2

Это потому, что @v2 анализируется до @ v1 механизмом mysql.

Как заставить порядок назначения получить такой результат:

@v1 | @v2
---------
 0  |  2

РЕДАКТИРОВАТЬ: это не тот же вопрос, что и: присваивание переменной с mysql

Вот вопрос о том, чтобы форсировать порядок присвоения, а не о том, почему результат не является ожидаемым.

ОБНОВЛЕНИЕ: когда вы используете левое внешнее соединение, результат также странный:

SET @v1=0;

SELECT @v1
FROM Account other 
LEFT OUTER JOIN SimpleValue f_PC ON f_PC.accountId=other.id AND f_PC.refShortcut='PC'  
WHERE CASE WHEN (other.context='44') THEN (@v1:=@v1+1) ELSE null END
ORDER BY @v1 ASC

В этом случае запрос возвращает 60 результатов, но значение @ v1 равно 120.

Если я удаляю левое внешнее соединение, значение v1 равно 60. Почему?

Ответы [ 2 ]

1 голос
/ 07 февраля 2011

В операторе select предложение переходит от LEFT к RIGHT, от TOP к BOTTOM, поэтому оно работает как положено (MS Access использует ту же стратегию).Однако в предложении WHERE все ставки отключены и выбран лучший фильтр.Вы можете форсировать его, используя тот факт, что оператор CASE требует оценки слева направо (с сохранением порядка представления).

WHERE CASE WHEN (@v1:=@v2) is not null THEN (@v2:=2) ELSE (@v2:=2) = 0 END

Эта сила предназначена для оценки (и присвоения 2 для @ v2) либоветвь, но ТОЛЬКО для 1-го запуска @ v1: = @ v2 возвращает ноль, а @ v2 становится 2, что сравнивается с 0 для общего FALSE.Во второй раз @v1 := @v2 [= 2] и (@v2:=2) приводят к 2 (что составляет true).

0 голосов
/ 07 февраля 2011

Как объясняется в ответах на ваш другой вопрос, ничто не гарантированно сработает.

В вашем конкретном случае перемещение назначений в часть запроса SELECT, кажется, работает:

SET @v1=0;
SET @v2=0;

SELECT (@v1:=@v2), (@v2:=2) 
FROM DUAL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...