diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp
index e8f35d11714d11e975ec595b9a584bfbd890b5ec..8c3c1a8cdffbf85b9a29de1daceeba5b4b00d7f8 100644
--- a/src/libs/sqlite/sqlitedatabase.cpp
+++ b/src/libs/sqlite/sqlitedatabase.cpp
@@ -30,7 +30,8 @@
 namespace Sqlite {
 
 SqliteDatabase::SqliteDatabase()
-    : m_journalMode(JournalMode::Wal)
+    : m_databaseBackend(*this),
+      m_journalMode(JournalMode::Wal)
 {
 }
 
diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h
index 854ecf975f89299ea90eb1969b771e784cec151d..1129cf3a066b181da5c5be5131d2b243ee11ce78 100644
--- a/src/libs/sqlite/sqlitedatabase.h
+++ b/src/libs/sqlite/sqlitedatabase.h
@@ -41,6 +41,7 @@ class SQLITE_EXPORT SqliteDatabase
 {
     friend class SqliteAbstractTransaction;
     friend class SqliteStatement;
+    friend class SqliteBackend;
 
 public:
     SqliteDatabase();
@@ -66,9 +67,10 @@ public:
 
     void execute(Utils::SmallStringView sqlStatement);
 
+    SqliteDatabaseBackend &backend();
+
 private:
     void initializeTables();
-    SqliteDatabaseBackend &backend();
 
 
 private:
diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp
index eb7a14a05a2bef327ab1ec99a65accf30f97c83b..cb346a8654f0eec2da0c975170429aad8373d76f 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.cpp
+++ b/src/libs/sqlite/sqlitedatabasebackend.cpp
@@ -48,8 +48,9 @@
 
 namespace Sqlite {
 
-SqliteDatabaseBackend::SqliteDatabaseBackend()
-    : m_databaseHandle(nullptr),
+SqliteDatabaseBackend::SqliteDatabaseBackend(SqliteDatabase &database)
+    : m_database(database),
+      m_databaseHandle(nullptr),
       m_cachedTextEncoding(Utf8)
 {
 }
@@ -124,8 +125,7 @@ sqlite3 *SqliteDatabaseBackend::sqliteDatabaseHandle()
 
 void SqliteDatabaseBackend::setPragmaValue(Utils::SmallStringView pragmaKey, Utils::SmallStringView newPragmaValue)
 {
-    SqliteReadWriteStatement statement(Utils::SmallString{"PRAGMA ", pragmaKey, "='", newPragmaValue, "'"}, *this);
-    statement.step();
+    execute(Utils::SmallString{"PRAGMA ", pragmaKey, "='", newPragmaValue, "'"});
     Utils::SmallString pragmeValueInDatabase = toValue<Utils::SmallString>("PRAGMA " + pragmaKey);
 
     checkPragmaValue(pragmeValueInDatabase, newPragmaValue);
@@ -160,7 +160,7 @@ TextEncoding SqliteDatabaseBackend::textEncoding()
 
 Utils::SmallStringVector SqliteDatabaseBackend::columnNames(Utils::SmallStringView tableName)
 {
-    SqliteReadWriteStatement statement("SELECT * FROM " + tableName, *this);
+    SqliteReadWriteStatement statement("SELECT * FROM " + tableName, m_database);
     return statement.columnNames();
 }
 
@@ -176,7 +176,7 @@ int SqliteDatabaseBackend::totalChangesCount()
 
 void SqliteDatabaseBackend::execute(Utils::SmallStringView sqlStatement)
 {
-    SqliteReadWriteStatement statement(sqlStatement, *this);
+    SqliteReadWriteStatement statement(sqlStatement, m_database);
     statement.step();
 }
 
@@ -391,7 +391,7 @@ void SqliteDatabaseBackend::throwException(const char *whatHasHappens) const
 template <typename Type>
 Type SqliteDatabaseBackend::toValue(Utils::SmallStringView sqlStatement)
 {
-    SqliteReadWriteStatement statement(sqlStatement, *this);
+    SqliteReadWriteStatement statement(sqlStatement, m_database);
 
     statement.next();
 
diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h
index d7027e0ba4e2c134683af1791030d73c4e915b3f..cb9e26e464ace5255f4ff1a3aca50f8051445c16 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.h
+++ b/src/libs/sqlite/sqlitedatabasebackend.h
@@ -33,13 +33,17 @@ struct sqlite3;
 
 namespace Sqlite {
 
+class SqliteDatabase;
+
 class SQLITE_EXPORT SqliteDatabaseBackend
 {
 public:
-
-    SqliteDatabaseBackend();
+    SqliteDatabaseBackend(SqliteDatabase &database);
     ~SqliteDatabaseBackend();
 
+    SqliteDatabaseBackend(const SqliteDatabase &database) = delete;
+    SqliteDatabase &operator=(const SqliteDatabase &database) = delete;
+
     void setMmapSize(qint64 defaultSize, qint64 maximumSize);
     void activateMultiThreading();
     void activateLogging();
@@ -59,8 +63,6 @@ public:
     void setTextEncoding(TextEncoding textEncoding);
     TextEncoding textEncoding();
 
-
-
     Utils::SmallStringVector columnNames(Utils::SmallStringView tableName);
 
     int changesCount();
@@ -105,6 +107,7 @@ protected:
     Q_NORETURN void throwException(const char *whatHasHappens) const;
 
 private:
+    SqliteDatabase &m_database;
     sqlite3 *m_databaseHandle;
     TextEncoding m_cachedTextEncoding;
 
diff --git a/src/libs/sqlite/sqlitereadstatement.h b/src/libs/sqlite/sqlitereadstatement.h
index 02c998fb5d1e7b67683900015306da326c60455b..55bd5c15fbb991668963cbb38aa8b0eea4e70305 100644
--- a/src/libs/sqlite/sqlitereadstatement.h
+++ b/src/libs/sqlite/sqlitereadstatement.h
@@ -42,10 +42,13 @@ public:
     using SqliteStatement::columnCount;
     using SqliteStatement::columnNames;
     using SqliteStatement::bind;
+    using SqliteStatement::bindValues;
+    using SqliteStatement::bindNameValues;
     using SqliteStatement::bindingIndexForName;
     using SqliteStatement::setBindingColumnNames;
     using SqliteStatement::bindingColumnNames;
     using SqliteStatement::toValue;
+    using SqliteStatement::database;
 
 protected:
     void checkIsReadOnlyStatement();
diff --git a/src/libs/sqlite/sqlitereadwritestatement.cpp b/src/libs/sqlite/sqlitereadwritestatement.cpp
index b642675e0a92a7e8c5c6446f1eb336335660e146..c7d8e468d916691b5e5fd828d43465aea42d406f 100644
--- a/src/libs/sqlite/sqlitereadwritestatement.cpp
+++ b/src/libs/sqlite/sqlitereadwritestatement.cpp
@@ -33,10 +33,4 @@ SqliteReadWriteStatement::SqliteReadWriteStatement(Utils::SmallStringView sqlSta
 {
 }
 
-SqliteReadWriteStatement::SqliteReadWriteStatement(Utils::SmallStringView sqlStatement,
-                                                   SqliteDatabaseBackend &backend)
-    : SqliteStatement(sqlStatement, backend)
-{
-}
-
 } // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitereadwritestatement.h b/src/libs/sqlite/sqlitereadwritestatement.h
index 8488fcc67c7e956620d17a4e5b855acbab724128..8f93ff85bed073f991eb10d4576c89c3c1573873 100644
--- a/src/libs/sqlite/sqlitereadwritestatement.h
+++ b/src/libs/sqlite/sqlitereadwritestatement.h
@@ -37,9 +37,11 @@ public:
     SqliteReadWriteStatement(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
 
     using SqliteStatement::next;
-    using SqliteStatement::step;
+    using SqliteStatement::execute;
     using SqliteStatement::reset;
     using SqliteStatement::bind;
+    using SqliteStatement::bindValues;
+    using SqliteStatement::bindNameValues;
     using SqliteStatement::bindingIndexForName;
     using SqliteStatement::setBindingColumnNames;
     using SqliteStatement::bindingColumnNames;
@@ -49,10 +51,9 @@ public:
     using SqliteStatement::columnCount;
     using SqliteStatement::columnNames;
     using SqliteStatement::toValue;
-
-private:
-    explicit SqliteReadWriteStatement(Utils::SmallStringView sqlStatement,
-                                      SqliteDatabaseBackend &backend);
+    using SqliteStatement::database;
+    using SqliteStatement::write;
+    using SqliteStatement::writeNamed;
 };
 
 } // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitestatement.cpp b/src/libs/sqlite/sqlitestatement.cpp
index 37081ca106466369384b86826f69a828738d5c68..fee0130acc7d1fbdbba56b2aeba7c934ef0afa6e 100644
--- a/src/libs/sqlite/sqlitestatement.cpp
+++ b/src/libs/sqlite/sqlitestatement.cpp
@@ -43,14 +43,8 @@
 namespace Sqlite {
 
 SqliteStatement::SqliteStatement(Utils::SmallStringView sqlStatement, SqliteDatabase &database)
-    : SqliteStatement(sqlStatement, database.backend())
-{
-
-}
-
-SqliteStatement::SqliteStatement(Utils::SmallStringView sqlStatement, SqliteDatabaseBackend &databaseBackend)
     : m_compiledStatement(nullptr, deleteCompiledStatement),
-      m_databaseBackend(databaseBackend),
+      m_database(database),
       m_bindingParameterCount(0),
       m_columnCount(0),
       m_isReadyToFetchValues(false)
@@ -146,6 +140,11 @@ void SqliteStatement::step() const
     next();
 }
 
+void SqliteStatement::execute() const
+{
+    next();
+}
+
 int SqliteStatement::columnCount() const
 {
     return m_columnCount;
@@ -203,7 +202,7 @@ template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, q
 template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, double value);
 template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, Utils::SmallStringView text);
 
-int SqliteStatement::bindingIndexForName(Utils::SmallStringView name)
+int SqliteStatement::bindingIndexForName(Utils::SmallStringView name) const
 {
     return  sqlite3_bind_parameter_index(m_compiledStatement.get(), name.data());
 }
@@ -241,12 +240,12 @@ void SqliteStatement::prepare(Utils::SmallStringView sqlStatement)
 
 sqlite3 *SqliteStatement::sqliteDatabaseHandle() const
 {
-    return m_databaseBackend.sqliteDatabaseHandle();
+    return m_database.backend().sqliteDatabaseHandle();
 }
 
 TextEncoding SqliteStatement::databaseTextEncoding()
 {
-     return m_databaseBackend.textEncoding();
+     return m_database.backend().textEncoding();
 }
 
 bool SqliteStatement::checkForStepError(int resultCode) const
@@ -359,6 +358,11 @@ QString SqliteStatement::columnName(int column) const
     return QString::fromUtf8(sqlite3_column_name(m_compiledStatement.get(), column));
 }
 
+SqliteDatabase &SqliteStatement::database() const
+{
+    return m_database;
+}
+
 static Utils::SmallString textForColumn(sqlite3_stmt *sqlStatment, int column)
 {
     const char *text =  reinterpret_cast<const char*>(sqlite3_column_text(sqlStatment, column));
diff --git a/src/libs/sqlite/sqlitestatement.h b/src/libs/sqlite/sqlitestatement.h
index 1c748a35443246f906ce237b5714bee604008adc..5f74c267ef380f05f79ed0d871db1193d770313b 100644
--- a/src/libs/sqlite/sqlitestatement.h
+++ b/src/libs/sqlite/sqlitestatement.h
@@ -51,6 +51,7 @@ protected:
 
     bool next() const;
     void step() const;
+    void execute() const;
     void reset() const;
 
     template<typename Type>
@@ -64,10 +65,36 @@ protected:
     void bind(int index, double value);
     void bind(int index, Utils::SmallStringView value);
 
+    template<typename ... Values>
+    void bindValues(Values ... values)
+    {
+        bindValuesByIndex(1, values...);
+    }
+
+    template<typename ... Values>
+    void write(Values ... values)
+    {
+        bindValuesByIndex(1, values...);
+        execute();
+    }
+
+    template<typename ... Values>
+    void bindNameValues(Values ... values)
+    {
+        bindValuesByName(values...);
+    }
+
+    template<typename ... Values>
+    void writeNamed(Values ... values)
+    {
+        bindValuesByName(values...);
+        execute();
+    }
+
     template <typename Type>
     void bind(Utils::SmallStringView name, Type value);
 
-    int bindingIndexForName(Utils::SmallStringView name);
+    int bindingIndexForName(Utils::SmallStringView name) const;
 
     void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames);
     const Utils::SmallStringVector &bindingColumnNames() const;
@@ -107,14 +134,43 @@ protected:
 
     QString columnName(int column) const;
 
+    SqliteDatabase &database() const;
+
 protected:
     explicit SqliteStatement(Utils::SmallStringView sqlStatement,
                              SqliteDatabaseBackend &databaseBackend);
 
+private:
+    template<typename Type>
+    void bindValuesByIndex(int index, Type value)
+    {
+        bind(index, value);
+    }
+
+    template<typename Type, typename ... Value>
+    void bindValuesByIndex(int index, Type value, Value ... values)
+    {
+        bind(index, value);
+        bindValuesByIndex(index + 1, values...);
+    }
+
+    template<typename Type>
+    void bindValuesByName(Utils::SmallStringView name, Type value)
+    {
+       bind(bindingIndexForName(name), value);
+    }
+
+    template<typename Type, typename ... Values>
+    void bindValuesByName(Utils::SmallStringView name, Type value, Values ... values)
+    {
+       bind(bindingIndexForName(name), value);
+       bindValuesByName(values...);
+    }
+
 private:
     std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> m_compiledStatement;
     Utils::SmallStringVector m_bindingColumnNames;
-    SqliteDatabaseBackend &m_databaseBackend;
+    SqliteDatabase &m_database;
     int m_bindingParameterCount;
     int m_columnCount;
     mutable bool m_isReadyToFetchValues;
diff --git a/src/libs/sqlite/sqlitewritestatement.h b/src/libs/sqlite/sqlitewritestatement.h
index 907222423d7cc5eae1b615e35b420cfbe4a6fb5e..a9a1b3de37308599e7e01e8157a7317f00f3e42c 100644
--- a/src/libs/sqlite/sqlitewritestatement.h
+++ b/src/libs/sqlite/sqlitewritestatement.h
@@ -34,12 +34,17 @@ class SQLITE_EXPORT SqliteWriteStatement : private SqliteStatement
 public:
     explicit SqliteWriteStatement(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
 
-    using SqliteStatement::step;
+    using SqliteStatement::execute;
     using SqliteStatement::reset;
     using SqliteStatement::bind;
+    using SqliteStatement::bindValues;
+    using SqliteStatement::bindNameValues;
     using SqliteStatement::bindingIndexForName;
     using SqliteStatement::setBindingColumnNames;
     using SqliteStatement::bindingColumnNames;
+    using SqliteStatement::database;
+    using SqliteStatement::write;
+    using SqliteStatement::writeNamed;
 
 protected:
     void checkIsWritableStatement();
diff --git a/tests/unit/unittest/sqlitedatabasebackend-test.cpp b/tests/unit/unittest/sqlitedatabasebackend-test.cpp
index 88c7a53063f1354dc852fddf7166e260b7fe09b5..be93866671dd0bae57a824aec5f30199f552668a 100644
--- a/tests/unit/unittest/sqlitedatabasebackend-test.cpp
+++ b/tests/unit/unittest/sqlitedatabasebackend-test.cpp
@@ -25,6 +25,7 @@
 
 #include "googletest.h"
 
+#include <sqlitedatabase.h>
 #include <sqlitedatabasebackend.h>
 #include <sqliteexception.h>
 #include <sqlitewritestatement.h>
@@ -43,7 +44,8 @@ protected:
     void TearDown() override;
 
     Utils::PathString databaseFilePath = QDir::tempPath() + "/SqliteDatabaseBackendTest.db";
-    Sqlite::SqliteDatabaseBackend databaseBackend;
+    Sqlite::SqliteDatabase database;
+    Sqlite::SqliteDatabaseBackend &databaseBackend = database.backend();
 };
 
 using SqliteDatabaseBackendSlowTest = SqliteDatabaseBackend;
diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp
index 13a51253de7f8a4e1ca738e92e053de4e29025e9..3bf97e6d73d5a3235898b5e6f7d4cba7268a7652 100644
--- a/tests/unit/unittest/sqlitestatement-test.cpp
+++ b/tests/unit/unittest/sqlitestatement-test.cpp
@@ -35,8 +35,8 @@
 #include <vector>
 
 namespace {
-
 using testing::ElementsAre;
+using testing::PrintToString;
 
 using Sqlite::SqliteException;
 using Sqlite::SqliteDatabase;
@@ -44,12 +44,30 @@ using Sqlite::SqliteReadStatement;
 using Sqlite::SqliteReadWriteStatement;
 using Sqlite::SqliteWriteStatement;
 
+MATCHER_P3(HasValues, value1, value2, rowid,
+           std::string(negation ? "isn't" : "is")
+           + PrintToString(value1)
+           + ", " + PrintToString(value2)
+           + " and " + PrintToString(rowid)
+           )
+{
+    SqliteDatabase &database = arg.database();
+
+    SqliteReadStatement statement("SELECT name, number FROM test WHERE rowid=?", database);
+    statement.bind(1, rowid);
+
+    statement.next();
+
+    return statement.text(0) == value1 && statement.text(1) == value2;
+}
+
 class SqliteStatement : public ::testing::Test
 {
 protected:
      void SetUp() override;
      void TearDown() override;
 
+protected:
     SqliteDatabase database;
 };
 
@@ -250,6 +268,44 @@ TEST_F(SqliteStatement, RequestBindingNamesFromStatement)
     ASSERT_THAT(statement.bindingColumnNames(), ElementsAre("name", "number", "id"));
 }
 
+TEST_F(SqliteStatement, BindValues)
+{
+    SqliteWriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);
+
+    statement.bindValues("see", 7.23, 1);
+    statement.execute();
+
+    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
+}
+
+TEST_F(SqliteStatement, WriteValues)
+{
+    SqliteWriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);
+
+    statement.write("see", 7.23, 1);
+
+    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
+}
+
+TEST_F(SqliteStatement, BindNamedValues)
+{
+    SqliteWriteStatement statement("UPDATE test SET name=@name, number=@number WHERE rowid=@id", database);
+
+    statement.bindNameValues("@name", "see", "@number", 7.23, "@id", 1);
+    statement.execute();
+
+    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
+}
+
+TEST_F(SqliteStatement, WriteNamedValues)
+{
+    SqliteWriteStatement statement("UPDATE test SET name=@name, number=@number WHERE rowid=@id", database);
+
+    statement.writeNamed("@name", "see", "@number", 7.23, "@id", 1);
+
+    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
+}
+
 TEST_F(SqliteStatement, ClosedDatabase)
 {
     database.close();