HOWTO · SQLite
Variables en SQLite
Este artículo trata sobre la declaración y el uso de variables en SQLite.
En esta página
SQLite SQL no tiene variables locales procedimentales que se declaren y asignen entre sentencias. En una aplicación, lo habitual es proporcionar los valores cambiantes mediante parámetros enlazados. Si varias sentencias de una misma conexión reutilizan valores, una tabla temporal puede guardar ese estado de SQL. Una expresión de tabla común (CTE) da nombre a valores para una sola sentencia. Como estos enfoques tienen distintos ámbitos, elige el que corresponda al tiempo durante el cual necesites el valor.
¿SQLite admite variables?
SQLite admite parámetros en sentencias preparadas, pero sus valores los proporciona la aplicación o el controlador de la base de datos. Un parámetro es un marcador de posición para un valor en una sentencia; no es una variable declarada por SQL ni puede sustituir el nombre de una tabla o columna. Por ejemplo, puedes enlazar un valor en SELECT * FROM products WHERE price >= ?. Usa la API de parámetros del controlador para asociar el marcador con la entrada.
El enlace mantiene los datos separados de la sintaxis SQL. Es la opción predeterminada adecuada para valores que proceden de usuarios, la configuración u otros datos de la aplicación. Para variar el nombre de una tabla o columna, elige el identificador de una lista permitida controlada por la aplicación y compón ese identificador por separado; no lo trates como un valor enlazable.
Usa parámetros enlazados para los valores
El siguiente ejemplo de Python usa el módulo estándar sqlite3 para crear filas de muestra y enlazar un umbral de precio. Es un ejemplo completo para el caso normal: el marcador de posición de SQL recibe un valor de Python, en vez de texto concatenado.
Ejecuta este ejemplo:
El bloque de código y sus etiquetas o resultados visibles se conservan sin cambios en inglés.
El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.
import sqlite3
connection = sqlite3.connect(":memory:")
connection.execute("CREATE TABLE products (name TEXT, price REAL)")
connection.executemany(
"INSERT INTO products (name, price) VALUES (?, ?)",
[("Notebook", 4.5), ("Keyboard", 25.0), ("Monitor", 180.0)],
)
minimum_price = 20
rows = connection.execute(
"SELECT name, price FROM products WHERE price >= ? ORDER BY price",
(minimum_price,),
).fetchall()
for name, price in rows:
print(f"{name}: {price:.2f}")
connection.close()
Un marcador posicional usa ?; los marcadores con nombre pueden adoptar formas como :minimum y recibir un diccionario del controlador como {"minimum": 20}. Usa el estilo de marcador y el método de enlace que admita tu controlador, y enlaza todos los valores de entrada en lugar de interpolarlos en la cadena SQL.
Usa una tabla temporal para reutilizar el estado de SQL
Una tabla temporal resulta útil cuando varias sentencias de una misma conexión necesitan leer o actualizar el mismo conjunto de valores. Créala con CREATE TEMP TABLE settings (name TEXT, value INTEGER), inserta filas mediante sentencias INSERT normales y consulta sus datos como los de cualquier otra tabla. Puedes actualizar filas entre sentencias y, al terminar, eliminar la tabla con DROP TABLE settings.
Las tablas temporales pertenecen a la conexión que las creó. Las sentencias de esa conexión pueden usarlas hasta que se eliminen o se cierre la conexión; otra conexión no las comparte. Una transacción determina si los cambios se confirman o se revierten, mientras que el ámbito de la conexión de la tabla temporal es una cuestión aparte. Una tabla temporal representa filas de estado de SQL, no una declaración de variables procedimentales, y no hace falta si un parámetro enlazado puede proporcionar el valor directamente.
Usa una CTE para valores de una sola sentencia
Una CTE da nombre a un resultado que utiliza la sentencia que viene a continuación. Por ejemplo, WITH limits AS (SELECT 20 AS minimum_price) SELECT name FROM products, limits WHERE products.price >= limits.minimum_price; define un valor y lo usa en la misma consulta. La CTE no crea una variable que puedan leer las sentencias posteriores. Úsala para que las entradas o los resultados intermedios de una consulta sean más fáciles de leer; usa una tabla temporal cuando los datos deban seguir disponibles en varias sentencias de una misma conexión.
Clases de almacenamiento de SQLite y CAST
Los valores de SQLite usan cinco clases de almacenamiento: NULL, INTEGER, REAL, TEXT y BLOB. Estas describen el valor almacenado durante la ejecución, no tipos de variables declaradas. Una columna puede tener un tipo declarado que le confiera afinidad, lo cual influye en cómo SQLite almacena y compara los valores; sin embargo, el sistema de tipos de SQLite no es un conjunto de declaraciones de variables procedimentales.
CAST(expression AS type) convierte una expresión según las reglas de conversión de SQLite. Se aplica al resultado de esa expresión; no cambia un parámetro, crea una variable ni modifica permanentemente un valor en otro lugar. Por ejemplo, CAST('42' AS INTEGER) expresa el valor de texto como un entero. La conversión puede depender de la entrada y del tipo de destino, así que valida las entradas de la aplicación cuando importe el formato aceptado, en vez de asumir que CAST sirve para validarlas. Convertir un valor tampoco es una forma general de obtener el código ASCII de sus caracteres.
Elige el enfoque adecuado
Usa parámetros enlazados para los valores que proporciona una aplicación, sobre todo si proceden de usuarios. Mantienen los valores separados del texto SQL y sirven para una sola sentencia sin mantener estado adicional. Usa una tabla temporal cuando varias sentencias de una misma conexión necesiten un conjunto de filas reutilizables o modificables. Usa una CTE cuando solo se necesite un valor o resultado intermedio en una sentencia. Son herramientas complementarias con distintos tiempos de vida, no tres formas de declarar una variable persistente de SQLite.