# Database Operations

Zephyr currently supports the following types of database interactions:

* Write.
* Read.
* Update.

On the guest level, there is no auth to handle so this is pretty straightforward as you don't have to grant any special permissions.

## Write

In the Zephyr VM, or better in the Mercury abstraction of the VM implementation, a write operation translates to a SQL insert statement and it is performed by providing a constructed `DatabaseDerive` object to the `EnvClient::put()` function:

<pre class="language-rust"><code class="lang-rust"><strong>#[derive(DatabaseDerive, Clone)]
</strong>#[with_name("test")]
struct TestTable {
    hello: ScVal,
}

#[no_mangle]
pub extern "C" fn on_close() {
    let env = EnvClient::new();
    // define the message
    let table = TestTable {
        hello: message.clone(),
    };
    
    table.put(&#x26;env);
}
</code></pre>

In this case, "table" is a `DatabaseDerive` object and represents a new row in the table.

## Read

Reading means returning an iterator (a vec currently) over `DatabaseDerive` elements, as many as the rows present in the requested table. It is done by simply calling `EnvClient::read()` while inferring the requested table type (which will automatically translate to reading from the corresponding table):

```rust
let rows = env.read::<TestTable>();
for row in rows {
    // ...
}
```

## Update

Updating lets you update a selection of the table by changing some rows with a new given one. You have to specify the conditions under which to change the rows, and the new row as a `DatabaseDerive` element:

```rust
let table = TestTable {
    hello: message1.clone(),
};

// note: message1 is an ScVal
env.update().column_equal_to_xdr("hello", &message).execute(&table)
```

In this snippet, all rows where the `hello` column equals to the `message` ScVal will be updated with the row defined by `table`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mercurydata.app/zephyr-full-customization/learn/database-interactions/database-operations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
