diff --git a/sql-statements/sql-statement-set-variable.md b/sql-statements/sql-statement-set-variable.md index f45739db6ffc5..b095869c2ec32 100644 --- a/sql-statements/sql-statement-set-variable.md +++ b/sql-statements/sql-statement-set-variable.md @@ -5,7 +5,11 @@ summary: An overview of the usage of SET [GLOBAL|SESSION] for the TiD # `SET [GLOBAL|SESSION] ` -The statement `SET [GLOBAL|SESSION]` modifies one of TiDB's built in variables, of either `SESSION` or `GLOBAL` scope. +The statement `SET [GLOBAL|SESSION]` modifies one of TiDB's built in variables. These variables can be [system variables](/system-variables.md) of either `SESSION` or `GLOBAL` scope or [user variables](/user-defined-variables.md). + +> **Warning:** +> +> User-defined variables are still an experimental feature. It is **NOT** recommended that you use them in the production environment. > **Note:** > @@ -13,13 +17,14 @@ The statement `SET [GLOBAL|SESSION]` modifies one of TiDB's built in variables, ## Synopsis -**SetStmt:** - -![SetStmt](/media/sqlgram/SetStmt.png) +```ebnf+diagram +SetVariableStmt ::= + "SET" Variable "=" Expression ("," Variable "=" Expression )* -**VariableAssignment:** - -![VariableAssignment](/media/sqlgram/VariableAssignment.png) +Variable ::= + ("GLOBAL" | "SESSION") SystemVariable +| UserVariable +``` ## Examples @@ -81,6 +86,21 @@ mysql> SHOW SESSION VARIABLES LIKE 'sql_mode'; 1 row in set (0.00 sec) ``` +User variables start with a `@`. + +```sql +SET @myvar := 5; +Query OK, 0 rows affected (0.00 sec) + +SELECT @myvar, @myvar + 1; ++--------+------------+ +| @myvar | @myvar + 1 | ++--------+------------+ +| 5 | 6 | ++--------+------------+ +1 row in set (0.00 sec) +``` + ## MySQL compatibility The following behavior differences apply: @@ -88,6 +108,7 @@ The following behavior differences apply: * Changes made with `SET GLOBAL` will be propagated to all TiDB instances in the cluster. This differs from MySQL, where changes do not propagate to replicas. * TiDB presents several variables as both readable and settable. This is required for MySQL compatibility, because it is common for both applications and connectors to read MySQL variables. For example: JDBC connectors both read and set query cache settings, despite not relying on the behavior. * Changes made with `SET GLOBAL` will persist through TiDB server restarts. This means that `SET GLOBAL` in TiDB behaves more similar to `SET PERSIST` as available in MySQL 8.0 and above. +* TiDB does not support `SET PERSIST` and `SET PERSIST_ONLY`, because TiDB persists global variables. ## See also diff --git a/user-defined-variables.md b/user-defined-variables.md index 6faac81c8cc50..ef81a7f0e6f99 100644 --- a/user-defined-variables.md +++ b/user-defined-variables.md @@ -17,48 +17,36 @@ The user-defined variables are session-specific, which means a user variable def ## Set the user-defined variables -You can use the `SET` statement to set a user-defined variable, and the syntax is `SET @var_name = expr [, @var_name = expr] ...;`. For example: - -{{< copyable "sql" >}} +You can use the [`SET` statement](/sql-statements/sql-statement-set-variable.md) to set a user-defined variable, and the syntax is `SET @var_name = expr [, @var_name = expr] ...;`. For example: ```sql SET @favorite_db = 'TiDB'; ``` -{{< copyable "sql" >}} - ```sql SET @a = 'a', @b = 'b', @c = 'c'; ``` For the assignment operator, you can also use `:=`. For example: -{{< copyable "sql" >}} - ```sql SET @favorite_db := 'TiDB'; ``` The content to the right of the assignment operator can be any valid expression. For example: -{{< copyable "sql" >}} - ```sql SET @c = @a + @b; ``` -{{< copyable "sql" >}} - ```sql -set @c = b'1000001' + b'1000001'; +SET @c = b'1000001' + b'1000001'; ``` ## Read the user-defined variables To read a user-defined variable, you can use the `SELECT` statement to query: -{{< copyable "sql" >}} - ```sql SELECT @a1, @a2, @a3 ``` @@ -89,16 +77,12 @@ Before the variable `@a4` is modified or the connection is closed, its value is If a hexadecimal literal or binary literal is used when setting the user-defined variable, TiDB will treat it as a binary string. If you want to set it to a number, you can manually add the `CAST` conversion, or use the numeric operator in the expression: -{{< copyable "sql" >}} - ```sql SET @v1 = b'1000001'; SET @v2 = b'1000001'+0; SET @v3 = CAST(b'1000001' AS UNSIGNED); ``` -{{< copyable "sql" >}} - ```sql SELECT @v1, @v2, @v3; ``` @@ -113,8 +97,6 @@ SELECT @v1, @v2, @v3; If you refer to a user-defined variable that has not been initialized, it has a value of NULL and a type of string. -{{< copyable "sql" >}} - ```sql SELECT @not_exist; ``` @@ -129,8 +111,6 @@ SELECT @not_exist; In addition to using the `SELECT` statement to read the user-defined variables, another common usage is the `PREPARE` statement. For example: -{{< copyable "sql" >}} - ```sql SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; PREPARE stmt FROM @s; @@ -149,8 +129,6 @@ EXECUTE stmt USING @a, @b; The contents of the user-defined variables are not recognized as identifiers in the SQL statements. For example: -{{< copyable "sql" >}} - ```sql SELECT * from t; ``` @@ -163,8 +141,6 @@ SELECT * from t; +---+ ``` -{{< copyable "sql" >}} - ```sql SET @col = "`a`"; SELECT @col FROM t;