2011-10-12 25 views
67

Quiero declarar una variable en sqlite y utilizarlo en operación de inserciónDeclarar variable en sqlite y usarlo

como en MS SQL

Declare @name as varchar(10) 

set name = 'name' 

Select * from table where name = @name 

Por ejemplo, necesitaré para obtener last_insert_row y el uso inserción en

he encontrado algo acerca de la unión pero no lo hice de verdad totalmente entendido

+6

sqlite no es compatible con esto. –

Respuesta

68

SQLite no admite la sintaxis de variable nativa, pero puede lograr prácticamente lo mismo utilizando una tabla temporal en memoria.

He utilizado el siguiente enfoque para proyectos grandes y funciona como un encanto.

/* Create in-memory temp table for variables */ 
    BEGIN; 

    PRAGMA temp_store = 2; 
    CREATE TEMP TABLE _Variables(Name TEXT PRIMARY KEY, RealValue REAL, IntegerValue INTEGER, BlobValue BLOB, TextValue TEXT); 

    /* Declaring a variable */ 
    INSERT INTO _Variables (Name) VALUES ('VariableName'); 

    /* Assigning a variable (pick the right storage class) */ 
    UPDATE _Variables SET IntegerValue = ... WHERE Name = 'VariableName'; 

    /* Getting variable value (use within expression) */ 
    ... (SELECT coalesce(RealValue, IntegerValue, BlobValue, TextValue) FROM _Variables WHERE Name = 'VariableName' LIMIT 1) ... 

    DROP TABLE _Variables; 
    END; 
+0

¿Para qué se usan estos corchetes []? – WindRider

+1

@WindRider: para evitar cualquier conflicto con palabras reservadas. Un hábito mío pero innecesario en este caso, por lo que se eliminan. –

+0

Esto funciona, pero hay algunas observaciones, probé esto en spatialite, y allí dice que no puede cambiar el almacén temporal desde dentro de una transacción. Además, creo que te falta un punto y coma después de BEGIN. Tx para compartir esta solución. –

1

Intente utilizar valores de encuadernación. No puede usar variables como lo hace en T-SQL pero puede usar "parámetros". Espero que el siguiente enlace sea útil. Binding Values

+18

puede enriquecer su respuesta dando ejemplos. Los enlaces se pueden mover pero sus ejemplos estarán aquí para referencia futura. – Pabluez

34

La solución de Herman funciona, pero se puede simplificar porque Sqlite permite almacenar cualquier tipo de valor en cualquier campo.

Aquí es una versión más simple que utiliza un campo Value declarada como TEXT para almacenar cualquier valor:

CREATE TEMP TABLE IF NOT EXISTS Variables (Name TEXT PRIMARY KEY, Value TEXT); 

INSERT OR REPLACE INTO Variables VALUES ('VarStr', 'Val1'); 
INSERT OR REPLACE INTO Variables VALUES ('VarInt', 123); 
INSERT OR REPLACE INTO Variables VALUES ('VarBlob', x'12345678'); 

SELECT Value 
    FROM Variables 
WHERE Name = 'VarStr' 
UNION ALL 
SELECT Value 
    FROM Variables 
WHERE Name = 'VarInt' 
UNION ALL 
SELECT Value 
    FROM Variables 
WHERE Name = 'VarBlob'; 
5

solución de Herman trabajó para mí, pero el ... me había mezclado un poco. Incluyo la demo que trabajé en función de su respuesta. Las características adicionales en mi respuesta incluyen soporte de clave externa, incremento automático de claves y uso de la función last_insert_rowid() para obtener la última clave generada automáticamente en una transacción.

Mi necesidad de esta información surgió cuando pulsé una transacción que requería tres claves foráneas, pero solo pude obtener la última con last_insert_rowid().

PRAGMA foreign_keys = ON; -- sqlite foreign key support is off by default 
PRAGMA temp_store = 2;  -- store temp table in memory, not on disk 

CREATE TABLE Foo(
    Thing1 INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL 
); 

CREATE TABLE Bar(
    Thing2 INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
    FOREIGN KEY(Thing2) REFERENCES Foo(Thing1) 
); 

BEGIN TRANSACTION; 

CREATE TEMP TABLE _Variables(Key TEXT, Value INTEGER); 

INSERT INTO Foo(Thing1) 
VALUES(2); 

INSERT INTO _Variables(Key, Value) 
VALUES('FooThing', last_insert_rowid()); 

INSERT INTO Bar(Thing2) 
VALUES((SELECT Value FROM _Variables WHERE Key = 'FooThing')); 

DROP TABLE _Variables; 

END TRANSACTION; 
Cuestiones relacionadas