Files
sqlgen/docs/update.md
2025-07-23 22:32:26 +02:00

4.0 KiB

sqlgen::update

The sqlgen::update interface provides a type-safe way to update records in a SQL database. It supports composable query building with where clauses to specify which records should be updated, and allows setting multiple columns to either literal values or other column values.

Usage

Basic Update

Update specific columns in a table:

const auto conn = sqlgen::sqlite::connect("database.db");

using namespace sqlgen;
using namespace sqlgen::literals;

const auto query = update<Person>("age"_c.set(100), "first_name"_c.set("New Name"));

query(conn).value();

This generates the following SQL:

UPDATE "Person" 
SET "age" = 100, "first_name" = 'New Name';

Note that conn is actually a connection wrapped into an sqlgen::Result<...>. This means you can use monadic error handling and fit this into a single line:

// sqlgen::Result<Ref<Connection>>
const auto result = sqlgen::sqlite::connect("database.db").and_then(
                        update<Person>("age"_c.set(100), "first_name"_c.set("New Name")));

Please refer to the documentation on sqlgen::Result<...> for more information on error handling.

With where clause

Update specific records using a where clause:

using namespace sqlgen;
using namespace sqlgen::literals;

const auto query = update<Person>("age"_c.set(100)) |
                   where("first_name"_c == "Hugo");

query(conn).value();

This generates the following SQL:

UPDATE "Person"
SET "age" = 100
WHERE "first_name" = 'Hugo';

Note that "..."_c refers to the name of the column. If such a field does not exist on the struct Person, the code will fail to compile. It is defined in the namespace sqlgen::literals.

You can also use monadic error handling here:

using namespace sqlgen;
using namespace sqlgen::literals;

const auto query = update<Person>("age"_c.set(100)) |
                   where("first_name"_c == "Hugo");

// sqlgen::Result<Ref<Connection>>
const auto result = sqlite::connect("database.db").and_then(query);

Setting Columns to Other Column Values

You can set a column's value to another column's value:

using namespace sqlgen;
using namespace sqlgen::literals;

const auto query = update<Person>("first_name"_c.set("last_name"_c)) |
                   where("age"_c > 18);

query(conn).value();

This generates the following SQL:

UPDATE "Person"
SET "first_name" = "last_name"
WHERE "age" > 18;

Example: Full Query Composition

using namespace sqlgen;
using namespace sqlgen::literals;

const auto query = update<Person>(
                    "first_name"_c.set("last_name"_c),
                    "age"_c.set(100)) |
                   where("age"_c > 0);

const auto result = query(conn);

if (!result) {
    // Error handling
}

This generates the following SQL:

UPDATE "Person"
SET 
    "first_name" = "last_name",
    "age" = 100
WHERE "age" > 0;

It is strongly recommended that you use using namespace sqlgen and using namespace sqlgen::literals. However, if you do not want to do that, you can rewrite the example above as follows:

const auto query = sqlgen::update<Person>(
                    sqlgen::col<"first_name">.set(sqlgen::col<"last_name">),
                    sqlgen::col<"age">.set(100)) |
                   sqlgen::where(sqlgen::col<"age"> > 0);

const auto result = query(conn);

Notes

  • You must specify at least one column to update
  • The where clause is optional - if omitted, all records will be updated
  • The Result<Ref<Connection>> type provides error handling; use .value() to extract the result (will throw an exception if there's an error) or handle errors as needed or refer to the documentation on sqlgen::Result<...> for other forms of error handling
  • "..."_c refers to the name of the column. It is defined in the namespace sqlgen::literals.
  • You can set columns to either literal values or other column values
  • The update operation is atomic - either all specified columns are updated or none are