From 91a25f087840be556d399fe68d6a3155d7d5dc79 Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Tue, 7 Jan 2025 18:09:09 +0000 Subject: [PATCH] [D1] Adding information on `D1PreparedStatement` object. (#19051) * Adding information on D1PreparedStatement object. * Relocating `bind` documentation, tweaking docs to accommodate this change. * Adding an example in-situ for convenience for readers. --- .../docs/d1/worker-api/d1-database.mdx | 50 +++---------- .../d1/worker-api/prepared-statements.mdx | 75 ++++++++++++++++++- 2 files changed, 83 insertions(+), 42 deletions(-) diff --git a/src/content/docs/d1/worker-api/d1-database.mdx b/src/content/docs/d1/worker-api/d1-database.mdx index e3b0ebe834f1e4..1896c447bc9533 100644 --- a/src/content/docs/d1/worker-api/d1-database.mdx +++ b/src/content/docs/d1/worker-api/d1-database.mdx @@ -35,61 +35,29 @@ const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bin #### Return values -- None. +- D1PreparedStatement: + - An object which only contains methods. Refer to [Prepared statement methods](/d1/worker-api/prepared-statements/). #### Guidance -- D1 follows the [SQLite convention](https://www.sqlite.org/lang_expr.html#varparam) for prepared statements parameter binding. Currently, D1 only supports Ordered (`?NNNN`) and Anonymous (`?`) parameters. In the future, D1 will support named parameters as well. - - | Syntax | Type | Description | - | ------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | `?NNN` | Ordered | A question mark followed by a number `NNN` holds a spot for the `NNN`-th parameter. `NNN` must be between `1` and `SQLITE_MAX_VARIABLE_NUMBER` | - | `?` | Anonymous | A question mark that is not followed by a number creates a parameter with a number one greater than the largest parameter number already assigned. If this means the parameter number is greater than `SQLITE_MAX_VARIABLE_NUMBER`, it is an error. This parameter format is provided for compatibility with other database engines. But because it is easy to miscount the question marks, the use of this parameter format is discouraged. Programmers are encouraged to use one of the symbolic formats below or the `?NNN` format above instead. | - - To bind a parameter, use the `.bind` method. +You can use the `bind` method to dynamically bind a value into the query statement, as shown below. - Order and anonymous examples: +- Example of a static statement without using `bind`: ```js - const stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(""); + const stmt = db + .prepare("SELECT * FROM Customers WHERE CompanyName = Alfreds Futterkiste AND CustomerId = 1") ``` +- Example of an ordered statement using `bind`: + ```js const stmt = db .prepare("SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?") .bind("Alfreds Futterkiste", 1); ``` - ```js - const stmt = db - .prepare("SELECT * FROM Customers WHERE CompanyName = ?2 AND CustomerId = ?1") - .bind(1, "Alfreds Futterkiste"); - ``` - -#### Static statements - -D1 API supports static statements. Static statements are SQL statements where the variables have been hard coded. When writing a static statement, you manually type the variable within the statement string. - -:::note -The recommended approach is to bind parameters to create a prepared statement (which are precompiled objects used by the database) to run the SQL. Prepared statements lead to faster overall execution and prevent SQL injection attacks. -::: - -Example of a prepared statement with dynamically bound value: - -```js -const someVariable = `Bs Beverages`; -const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); -// A variable (someVariable) will replace the placeholder '?' in the query. -// `stmt` is a prepared statement. -``` - -Example of a static statement: - -```js -const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = Bs Beverages"); -// "Bs Beverages" is hard-coded into the query. -// `stmt` is a static statement. -``` +Refer to the [`bind` method documentation](/d1/worker-api/prepared-statements/#bind) for more information. ### `batch()` diff --git a/src/content/docs/d1/worker-api/prepared-statements.mdx b/src/content/docs/d1/worker-api/prepared-statements.mdx index 89e0f0065effaa..d54cf6c3740b7b 100644 --- a/src/content/docs/d1/worker-api/prepared-statements.mdx +++ b/src/content/docs/d1/worker-api/prepared-statements.mdx @@ -11,6 +11,79 @@ This chapter documents the various ways you can run and retrieve the results of ## Methods +### `bind()` + +Binds a parameter to the prepared statement. + +```js +const someVariable = `Bs Beverages`; +const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); +``` + +#### Parameter + +- Variable: + - The variable to be appended into the prepared statement. See [guidance](#guidance) below. + +#### Return values + +- D1PreparedStatement: + - A `D1PreparedStatement` where the input parameter has been included in the statement. + +#### Guidance + +- D1 follows the [SQLite convention](https://www.sqlite.org/lang_expr.html#varparam) for prepared statements parameter binding. Currently, D1 only supports Ordered (`?NNNN`) and Anonymous (`?`) parameters. In the future, D1 will support named parameters as well. + + | Syntax | Type | Description | + | ------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | `?NNN` | Ordered | A question mark followed by a number `NNN` holds a spot for the `NNN`-th parameter. `NNN` must be between `1` and `SQLITE_MAX_VARIABLE_NUMBER` | + | `?` | Anonymous | A question mark that is not followed by a number creates a parameter with a number one greater than the largest parameter number already assigned. If this means the parameter number is greater than `SQLITE_MAX_VARIABLE_NUMBER`, it is an error. This parameter format is provided for compatibility with other database engines. But because it is easy to miscount the question marks, the use of this parameter format is discouraged. Programmers are encouraged to use one of the symbolic formats below or the `?NNN` format above instead. | + + To bind a parameter, use the `.bind` method. + + Order and anonymous examples: + + ```js + const stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(""); + ``` + + ```js + const stmt = db + .prepare("SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?") + .bind("Alfreds Futterkiste", 1); + ``` + + ```js + const stmt = db + .prepare("SELECT * FROM Customers WHERE CompanyName = ?2 AND CustomerId = ?1") + .bind(1, "Alfreds Futterkiste"); + ``` + +#### Static statements + +D1 API supports static statements. Static statements are SQL statements where the variables have been hard coded. When writing a static statement, you manually type the variable within the statement string. + +:::note +The recommended approach is to bind parameters to create a prepared statement (which are precompiled objects used by the database) to run the SQL. Prepared statements lead to faster overall execution and prevent SQL injection attacks. +::: + +Example of a prepared statement with dynamically bound value: + +```js +const someVariable = `Bs Beverages`; +const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); +// A variable (someVariable) will replace the placeholder '?' in the query. +// `stmt` is a prepared statement. +``` + +Example of a static statement: + +```js +const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = Bs Beverages"); +// "Bs Beverages" is hard-coded into the query. +// `stmt` is a static statement. +``` + ### `run()` Runs the prepared query (or queries) and returns results. The returned results includes metadata. @@ -23,7 +96,7 @@ const returnValue = await stmt.run(); - None. -#### Return value +#### Return values - D1Result: - An object containing the success status, a meta object, and an array of objects containing the query results.