Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 114 additions & 71 deletions user-defined-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,134 +7,177 @@ aliases: ['/docs/v3.1/user-defined-variables/','/docs/v3.1/reference/sql/languag

# User-Defined Variables

This document describes the concept of user-defined variables in TiDB and the methods to set and read the user-defined variables.

> **Warning:**
>
> User-defined variables are still an experimental feature. It is **NOT** recommended that you use them in the production environment.

The format of the user-defined variables is `@var_name`. `@var_name` consists of alphanumeric characters, `_`, and `$`. The user-defined variables are case-insensitive.
The format of the user-defined variables is `@var_name`. The characters that compose `var_name` can be any characters that can compose an identifier, including the numbers `0-9`, the letters `a-zA-Z`, the underscore `_`, the dollar sign `$`, and the UTF-8 characters. In addition, it also includes the English period `.`. The user-defined variables are case-insensitive.

The user-defined variables are session-specific, which means a user variable defined by one client connection cannot be seen or used by other client connections.

## Set the user-defined variables

The user-defined variables are session specific, which means a user variable defined by one client cannot be seen or used by other clients.
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:

You can use the `SET` statement to set a user variable:
{{< copyable "sql" >}}

```sql
SET @var_name = expr [, @var_name = expr] ...
SET @favorite_db = 'TiDB';
```

or
{{< copyable "sql" >}}

```sql
SET @var_name := expr
SET @a = 'a', @b = 'b', @c = 'c';
```

For `SET`, you can use `=` or `:=` as the assignment operator.
For the assignment operator, you can also use `:=`. For example:

For example:
{{< copyable "sql" >}}

```sql
mysql> SET @a1=1, @a2=2, @a3:=4;
mysql> SELECT @a1, @a2, @t3, @a4 := @a1+@a2+@a3;
+------+------+------+--------------------+
| @a1 | @a2 | @a3 | @a4 := @a1+@a2+@a3 |
+------+------+------+--------------------+
| 1 | 2 | 4 | 7 |
+------+------+------+--------------------+
SET @favorite_db := 'TiDB';
```

Hexadecimal or bit values assigned to user variables are treated as binary strings in TiDB. To assign a hexadecimal or bit value as a number, use it in numeric context. For example, add `0` or use `CAST(... AS UNSIGNED)`:
The content to the right of the assignment operator can be any valid expression. For example:

{{< copyable "sql" >}}

```sql
mysql> SELECT @v1, @v2, @v3;
SET @c = @a + @b;
```

{{< copyable "sql" >}}

```sql
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
```

```
+------+------+------+
| @v1 | @v2 | @v3 |
| @a1 | @a2 | @a3 |
+------+------+------+
| A | 65 | 65 |
| 1 | 2 | 4 |
+------+------+------+
1 row in set (0.00 sec)
```

You can also assign values in the `SELECT` statement:

```sql
SELECT @a1, @a2, @a3, @a4 := @a1+@a2+@a3;
```

```
+------+------+------+--------------------+
| @a1 | @a2 | @a3 | @a4 := @a1+@a2+@a3 |
+------+------+------+--------------------+
| 1 | 2 | 4 | 7 |
+------+------+------+--------------------+
```

mysql> SET @v1 = b'1000001';
Query OK, 0 rows affected (0.00 sec)
Before the variable `@a4` is modified or the connection is closed, its value is always `7`。

mysql> SET @v2 = b'1000001'+0;
Query OK, 0 rows affected (0.00 sec)
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:

mysql> SET @v3 = CAST(b'1000001' AS UNSIGNED);
Query OK, 0 rows affected (0.00 sec)
{{< 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;
```

mysql> SELECT @v1, @v2, @v3;
```
+------+------+------+
| @v1 | @v2 | @v3 |
| @v1 | @v2 | @v3 |
+------+------+------+
| A | 65 | 65 |
| A | 65 | 65 |
+------+------+------+
1 row in set (0.00 sec)
```

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
mysql> select @not_exist;
SELECT @not_exist;
```

```
+------------+
| @not_exist |
+------------+
| NULL |
| NULL |
+------------+
1 row in set (0.00 sec)
```

The user-defined variables cannot be used as an identifier in the SQL statement. For example:
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
mysql> select * from t;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
PREPARE stmt FROM @s;
SET @a = 6;
SET @b = 8;
EXECUTE stmt USING @a, @b;
```

mysql> SET @col = "a";
Query OK, 0 rows affected (0.00 sec)
```
+------------+
| hypotenuse |
+------------+
| 10 |
+------------+
```

mysql> SELECT @col FROM t;
+------+
| @col |
+------+
| a |
+------+
1 row in set (0.00 sec)
The contents of the user-defined variables are not recognized as identifiers in the SQL statements. For example:

mysql> SELECT `@col` FROM t;
ERROR 1054 (42S22): Unknown column '@col' in 'field list'
{{< copyable "sql" >}}

mysql> SET @col = "`a`";
Query OK, 0 rows affected (0.00 sec)
```sql
SELECT * from t;
```

mysql> SELECT @col FROM t;
+------+
| @col |
+------+
| `a` |
+------+
1 row in set (0.01 sec)
```
+---+
| a |
+---+
| 1 |
+---+
```

An exception is that when you are constructing a string for use as a prepared statement to execute later:
{{< copyable "sql" >}}

```sql
mysql> PREPARE stmt FROM "SELECT @c FROM t";
Query OK, 0 rows affected (0.00 sec)
SET @col = "`a`";
SELECT @col FROM t;
```

mysql> EXECUTE stmt;
```
+------+
| @c |
| @col |
+------+
| a |
| `a` |
+------+
1 row in set (0.01 sec)

mysql> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)
```

For more information, see [User-Defined Variables in MySQL](https://dev.mysql.com/doc/refman/5.7/en/user-variables.html).