Что означает принуждение? Пользовательские переменные MySQL - PullRequest
5 голосов
/ 17 сентября 2009

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

что это значит? это как-то связано с ...

mysql> SET @a = 1; 
mysql> SET @A = @a; 
mysql> SELECT @a, @A;
mysql> SELECT @a, @A;
+------+------+
| @a    | @A    |
+------+------+
| 1 | 1 |
+------+------+
mysql> SET @a = 2;
mysql> SELECT @a, @A;
mysql> SELECT @a, @A;
+------+------+
| @a    | @A    |
+------+------+
| 2 | 2 |
+------+------+

где @A назначено 2, может быть потому, что оно "ссылается" на @a?

1 Ответ

9 голосов
/ 17 сентября 2009
SET @test = 'test';
SELECT COERCIBILITY(@test), COERCIBILITY('test');

---  ---
2    4

Из документации :

COERCIBILITY(str)

Возвращаемые значения имеют значения, указанные в следующей таблице. Более низкие значения имеют более высокий приоритет.

Coercibility  Meaning   Example
0             Explicit collation    Value with COLLATE clause
1             No collation          Concatenation of strings with different collations
2             Implicit collation    Column value
3             System constant       USER() return value
4             Coercible             Literal string
5             Ignorable             NULL or an expression derived from NULL

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

Выражение с большей принудительностью будет преобразовано в сопоставление выражения с более низкой принудительностью.

Эта функция полезна для устранения проблем с сопоставлением. Например, эти два запроса возвращают результаты в разном порядке.

Вот этот:

SELECT  col
FROM    (
        SELECT  DATABASE() AS col
        UNION ALL
        SELECT  'X'
        ) q
ORDER BY
        col;

----
'test'
'X'

А вот этот:

SET @t := 'X' COLLATE UTF8_BIN;
SELECT  col
FROM    (
        SELECT  DATABASE() AS col
        UNION ALL
        SELECT  @t
        ) q
ORDER BY
        col;

----
'X'
'test'

Почему так?

DATABASE() - это системная функция, возвращаемые значения которой имеют совокупность 3 и сопоставление базы данных по умолчанию UTF8_GENERAL_CI.

'X' в первом запросе является строковым литералом с принудительным значением 4.

Результат UNION всегда будет иметь наименьшую степень принуждения из всех значений (то есть 3) и сопоставление выражения с наименьшей степенью сопоставимости:

SELECT  col, COERCIBILITY(col), COLLATION(col)
FROM    (
        SELECT  DATABASE() AS col
        UNION ALL
        SELECT  'X'
        ) q
ORDER BY
        col;

--------
'test',  3, 'utf8_general_ci'
'X',     3, 'utf8_general_ci'

Во втором запросе @t - это переменная, которая содержит строковое значение с сопоставлением UTF8_BIN. Поскольку его принудительность ниже, чем у системной функции, в результирующем наборе используется сопоставление переменной.

Соотношение переменных равно 2, поэтому результат равен как переменным, так и параметрам сортировки:

SET @t := 'X' COLLATE UTF8_BIN;
SELECT  col, COERCIBILITY(col), COLLATION(col)
FROM    (
        SELECT  DATABASE() AS col
        UNION ALL
        SELECT  @t
        ) q
ORDER BY
        col;

--------
'X',     2, 'utf8_bin'
'test',  2, 'utf8_bin'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...