Skip to content

Parameterized Queries

⚠️ Not server-side prepare. pycubrid implements parameterized queries via client-side escape + interpolation, not via server-side PREPARE/EXECUTE. This differs from JDBC PreparedStatement. See pycubrid PARAMETER_BINDING.md for the full 1.x binding contract.

This directory demonstrates safe parameterized query patterns using pycubrid's qmark (?) placeholder style.

Recipes

Recipe Description
04_parameterized.py Topic redirect → canonical recipe at ../pycubrid/04_prepared.py (parameterized queries, batch executemany(), SQL injection safety)

Why parameterized queries?

Parameterized queries (passing values via ? placeholders and a separate parameters argument) are the correct way to send user-supplied values to the database. Never assemble SQL with f-strings or % formatting — that path leads to SQL injection.

pycubrid binding model

When you call:

cur.execute("SELECT * FROM users WHERE id = ? AND name = ?", [42, "Alice"])

pycubrid:

  1. Splits the SQL on unquoted ? placeholders.
  2. Formats each Python value as a SQL literal via _format_parameter() (strings escaped via single-quote doubling, None → NULL, etc.).
  3. Concatenates the segments and literals into one SQL string.
  4. Sends the fully-rendered SQL to CUBRID via PrepareAndExecutePacket.

The CAS function code is named PREPARE_AND_EXECUTE, but on this default path pycubrid sends a complete SQL string, not a separate typed parameter payload. Since pycubrid 1.12.0, cursor.executemany(sql, rows, prepared=True) is the exception: it sends one PREPARE plus an EXECUTE_ARRAY request with typed binds for each row instead of rendered literals. See pycubrid PARAMETER_BINDING.md for the full per-type mapping and explicit non-guarantees.