Parameters can be used like variables to store a value which can then be used in subsequent queries. To define a parameter in SurrealQL, use the LET statement. The name of the parameter should begin with a $ character.
Defining parameters within SurrealQL
-- Define the parameter LET$suffix = "Morgan Hitchcock"; -- Use the parameter CREATEpersonSETname="Tobie "+$suffix; -- (Another way to do the same) CREATEpersonSETname=string::join(" ", "Jaime", $suffix);
Response
[ { "id": "person:3vs17lb9eso9m7gd8mml", "name": "Tobie Morgan Hitchcock" } ]
[ { "id": "person:xh4zbns5mgmywe6bo1pi", "name": "Jaime Morgan Hitchcock" } ]
A parameter can store any value, including the result of a query.
-- Assuming the CREATE statements from the previous example LET$founders = (SELECT * FROMperson); RETURN$founders.name;
Response
[ "Tobie Morgan Hitchcock", "Jaime Morgan Hitchcock" ]
Parameters persist across the current connection, and thus can be reused between different namespaces and databases. In the example below, a created person record assigned to a parameter is reused in a query in a completely different namespace and database.
LET$billy = CREATEONLYperson:billySETname="Billy"; -- Fails as `person:billy` already exists CREATEpersonCONTENT$billy;
USENAMESPACEother_namespace; USEDATABASEother_database; -- Succeeds as `person:billy` does not yet exist in this namespace and database CREATEpersonCONTENT$billy;
Parameters can be defined using SurrealQL as shown above, or can be passed in using the client libraries as request variables.
Redefining and shadowing parameters
Parameters in SurrealQL are immutable. The same parameter can be redefined using a LET statement.
Before SurrealDB 3.0, the = on its own was used as syntactic sugar for a LET statement. This has since been deprecated in order to make it clearer that parameters can be redeclared, but not modified.
'There was a problem with the database: Parse error: Variable declaration without `let` is deprecated --> [4:1] | 4 | $my_name = "Sypha"; | ^^^^^^^^^^^^^^^^^^^ replace with `let $my_name = ..` '
If the parameter is redefined inside another scope, the original value will be shadowed. Shadowing refers to when a value is temporarily obstructed by a new value of the same name until the new scope has completed.
LET$nums = [ [1,2], [3,4] ];
{ LET$nums = $nums.flatten(); -- Flattened into a single array, -- so $nums is shadowed as [1,2,3,4] RETURN$nums; };
-- Returns original unflattened $nums: -- [[1,2], [3,4]] RETURN$nums;
Even a parameter defined using a DEFINE PARAM statement can be shadowed.
DEFINEPARAM$USERNAMEVALUE"user@user.com";
LET$USERNAME = "some other email";
However, the parameter $USERNAME in this case is still defined as its original value, as can be seen via an INFO FOR DB statement.
As the shadowed $USERNAME parameter will persist over the length of the connection, the parameter $USERNAME will once again show up as its original defined value if the connection is discontinued and restarted.
Defining parameters within client libraries
SurrealDB's client libraries allow parameters to be passed in as JSON values, which are then converted to SurrealDB data types when the query is run. The following example show a variable being used within a SurrealQL query from the JavaScript library.
letpeople=awaitsurreal.query("SELECT * FROM article WHERE status INSIDE $status",{ status:["live","draft"], });
Reserved variable names
SurrealDB automatically predefines certain variables depending on the type of operation being performed. For example, $this and $parent are automatically predefined for subqueries so that the fields of one can be compared to another if necessary. In addition, the predefined variables $access, $auth, $token, and $session are protected variables used to give access to parts of the current database configuration and can never be overwritten.
INSERTINTOcity[ {id: "london", population: 9600000, year: 2023} ] ONDUPLICATEKEYUPDATE -- Stick old data into historical_data historical_data+={ year: year, population: population }, -- Then update current record with the new input using $input population=$input.population, year=$input.year;
Improvements to parameters and expressions in statements
Parameters and expressions have traditionally only been available in a limited fashion in SurrealQL statements. As of the alpha versions of SurrealDB 3.0, work is undergoing to allow parameters and expressions to be used in many places that were not possible before.
{ language_en: 'DEFINE TABLE language_en TYPE NORMAL SCHEMAFULL PERMISSIONS NONE', language_ie: 'DEFINE TABLE language_ie TYPE NORMAL SCHEMAFULL PERMISSIONS NONE', language_ja: 'DEFINE TABLE language_ja TYPE NORMAL SCHEMAFULL PERMISSIONS NONE', language_uk: 'DEFINE TABLE language_uk TYPE NORMAL SCHEMAFULL PERMISSIONS NONE' }
REMOVE statements
Parameterization in REMOVE statements is particularly useful in the context of testing.
FOR$tableIN["test_user", "test_client"]{ DEFINETABLE$table; // Do some tests REMOVETABLE$table; };
The following example shows an example of a test that might be performed using a REMOVE FIELD statement. Here, the INFO FOR TABLE statement is used to dynamically capture the defined fields of a table, followed by the object::keys() function to retrieve each field as a string. The fields can then be removed one by one inside a REMOVE FIELD statement, with the time elapsed logged in a separate table.
DEFINEFUNCTIONfn::get_timeout() ->duration{ // Do some HTTP call to get status // Simulate the output with rand::enum() function rand::enum(100ms, 1s, 5s) };