This one's now properly fixed - thanks for the report, it shaped two features that just landed on main and will ship in the next Studio release.
DateTime values now bind as real date/time parameters
You no longer need ToSQLDate() or any cast. PreparedStatement.Bind accepts a DateTime directly, and the parameterised SelectSQL/ExecuteSQL overloads accept them too:
Var stmt As PreparedStatement = db.Prepare("INSERT INTO games (team, played_on) VALUES (?, ?)")
stmt.Bind(0, "Penguins")
stmt.Bind(1, DateTime.Now) # binds as a real date/timestamp parameter
stmt.ExecuteSQL()
Each provider maps this to its native types - PostgreSQL sends timestamp without time zone (which PostgreSQL assignment-casts into date and timestamptz columns), MySQL sends a native DATETIME, SQL Server uses DATETIME2, SQLite stores ISO-8601 text, and ODBC drivers get an SQL_TYPE_TIMESTAMP. The root cause of the original failure was that a ToSQLDate() result arrived as a String parameter, which Npgsql sends as text and PostgreSQL refuses for a date column without an explicit cast - that path is gone now. Reading back, DatabaseColumn.DateTimeValue converts date columns directly as well, including PostgreSQL date columns, so values round-trip without any conversion code.
There's also a new way to write inserts entirely without hand-building SQL.
The new DatabaseRow class pairs with AddRow on every database class, which covers this exact scenario:
Var row As New DatabaseRow
row.Column("Name") = "Penguins"
row.Column("Age") = 42
row.Column("Joined") = rs.Column("theDate").DateTimeValue
row.Column("Notes") = Nothing
Try
db.AddRow("Team", row)
Catch e As DatabaseException
MessageBox("DB Error: " + e.Message)
End Try
Each Column assignment is statically typed (String, Integer, Double, Decimal, Boolean, DateTime, MemoryBlock, or Nothing), so a mismatched value is a compile error rather than a runtime database error. The generated INSERT lists only the columns you assigned - unassigned columns keep their schema defaults - and Nothing inserts an explicit NULL. There's an AddRowAsync for awaited inserts too, and table/column identifiers are quoted per provider, so mixed-case and spaced names round-trip.
https://feedback.objo.dev/feature/1564