Объявите переменную в SQLite и используйте ее - PullRequest
80 голосов
/ 12 октября 2011

Я хочу объявить переменную в SQLite и использовать ее в операции insert.

Как и в MS SQL:

declare @name as varchar(10)
set name = 'name'
select * from table where name = @name

Например, мне нужно получить last_insert_row и используйте это в insert.

Я нашел кое-что о связывании, но я не совсем понял это.

Ответы [ 5 ]

86 голосов
/ 29 января 2013

SQLite не поддерживает собственный синтаксис переменных, но вы можете добиться практически того же, используя временную таблицу в памяти.

Я использовал приведенный ниже подход для больших проектов и работает как шарм.

    /* 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;
41 голосов
/ 10 июля 2014

Решение Германа работает, но его можно упростить, поскольку Sqlite позволяет хранить любой тип значения в любом поле.

Вот более простая версия, которая использует одно Value поле, объявленное как TEXT для хранения любого значения:

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';
8 голосов
/ 08 января 2016

Решение Германа сработало для меня, но ... меня немного перепутал.Я включил демонстрацию, которую я разработал, основываясь на его ответе.Дополнительные функции в моем ответе включают поддержку внешнего ключа, автоинкрементные ключи и использование функции last_insert_rowid() для получения последнего автоматически сгенерированного ключа в транзакции.

Мне понадобилась эта информация, когда я нажалтранзакция, которая требовала три внешних ключа, но я мог получить только последний с 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;
1 голос
/ 19 декабря 2011

Попробуйте использовать значения привязки. Вы не можете использовать переменные, как в T-SQL, но вы можете использовать «параметры». Я надеюсь, что следующая ссылка будет полезной. Binding Values ​​

0 голосов
/ 17 мая 2019

Для переменных только для чтения (используя одно и то же значение в запросе) используйте общее табличное выражение (CTE).

WITH var AS (SELECT 'name' AS name, 10 AS more)
SELECT *,(table.cost + var.more) AS result FROM table, var WHERE table.name = var.name

Предложение SQLite WITH

...