Skip to content

Commit

Permalink
[D1] Adding information on D1PreparedStatement object. (#19051)
Browse files Browse the repository at this point in the history
* Adding information on D1PreparedStatement object.

* Relocating `bind` documentation, tweaking docs to accommodate this change.

* Adding an example in-situ for convenience for readers.
  • Loading branch information
Oxyjun authored Jan 7, 2025
1 parent a81f442 commit 91a25f0
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 42 deletions.
50 changes: 9 additions & 41 deletions src/content/docs/d1/worker-api/d1-database.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,61 +35,29 @@ const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bin

#### Return values

- None.
- <code>D1PreparedStatement</code>: <Type text="Object"/>
- 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()`

Expand Down
75 changes: 74 additions & 1 deletion src/content/docs/d1/worker-api/prepared-statements.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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

- <code>Variable</code>: <Type text="string"/>
- The variable to be appended into the prepared statement. See [guidance](#guidance) below.

#### Return values

- <code>D1PreparedStatement</code>: <Type text="Object"/>
- 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.
Expand All @@ -23,7 +96,7 @@ const returnValue = await stmt.run();

- None.

#### Return value
#### Return values

- <code>D1Result</code>: <Type text="Object"/>
- An object containing the success status, a meta object, and an array of objects containing the query results.
Expand Down

0 comments on commit 91a25f0

Please sign in to comment.