Skip to content

Statements

LET

The LET statement allows you to create parameters to store any value, including the results of queries or the outputs of expressions. These parameters can then be referenced throughout your SurrealQL code, making your queries more dynamic and reusable.

The syntax for the LET statement is straightforward. The parameter name is prefixed with a $ symbol.

SurrealQL Syntax
LET $parameter [: @type_name] = @value;

You can use the LET statement to store simple values or query results. For example, storing a string value and then using it in a CREATE statement:

-- Define the parameter
LET $name = "tobie";
-- Use the parameter
CREATE person SET name = $name;

The LET statement is also useful for storing the results of a query, which can then be used in subsequent operations:

-- Define the parameter
LET $adults = SELECT * FROM person WHERE age > 18;
-- Use the parameter
UPDATE $adults SET adult = true;

SurrealQL allows you to define parameters based on conditional logic using IF ELSE statements:

LET $num = 10;

LET $num_type =
         IF type::is_int($num)     { "integer" }
    ELSE IF type::is_decimal($num) { "decimal" }
    ELSE IF type::is_float($num)   { "float"   };

RETURN $num_type;
Output
'integer'

You can define anonymous functions also known as closures using the LET statement. These functions can be used to encapsulate reusable logic and can be called from within your queries. Learn more about anonymous functions in the Data model section.

SurrealDB comes with pre-defined parameters that are accessible in any context. However, parameters created using LET are not accessible within the scope of these pre-defined parameters.

Some pre-defined parameters are protected and cannot be set using LET: $access, $auth, $token and $session, which hold parts of the current session. Attempting to redefine them will result in an error:

LET $auth = 1;
LET $session = 10;
Output
-------- Query 1 --------

"'auth' is a protected variable and cannot be set"

-------- Query 2 --------

"'session' is a protected variable and cannot be set"

These four names cannot be used as a FOR variable, a closure parameter or the argument of a defined function either, and each of these fails with the same error.

Other names are bound by SurrealDB itself inside a statement or clause: $this, $self, $parent, $value, $input, $before, $after and $event. A LET that is a statement of its own can use one of these names, and the statement that binds the name shadows it, so the parameter keeps its value outside that statement:

LET $before = "Before!";

-- Returns "Before!"
RETURN $before;

-- Returns the `person` records before deletion
DELETE person RETURN $before;

-- Returns "Before!" again
RETURN $before;

Available since: v4.0.0

A LET written inside a block, an IF branch, a function body or a closure body cannot use one of these names, because nothing would shadow it there. The whole statement is refused, and DEFINE FUNCTION refuses a function body that holds such a LET:

{ LET $value = 1; $value };
Output
"'value' is a protected variable and cannot be set"

From SurrealDB 4.0, a LET that no statement may hold is refused wherever it is written, even in code that never runs, such as after a RETURN or in an IF branch that is not taken. This covers a protected name, and a LET used as a value, such as SELECT * FROM t WHERE (LET $x = 1), which fails with LET statements can only appear at the top level of a query or inside a block expression. A VALUE clause or other stored clause that holds such a LET is refused when it is defined.

Type safety in a LET statement can be ensured by adding a : (a colon) and the type name after the LET keyword.

LET $number: int = "9";
Output
"Tried to set `$number`, but couldn't coerce value: Expected `int` but found `'9'`"

Multiple possible types can be specified in a LET statement by adding a | (vertical bar) in between each possible type.

LET $number: int | string = "9";

Even complex types such as objects can be included in a typed LET statement.

LET $error_info: 
  string | { error: string } = 
  { 
    error: "Something went wrong plz help" 
  };

For more information on this pattern, see the page on literals.

The LET statement stores values, the results of subqueries, and anonymous functions in parameters that later statements can use.

Was this page helpful?