在SQLite中声明变量并使用它


92

我想在SQLite中声明一个变量并在insert操作中使用它。

就像在MS SQL中一样:

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

例如,我将需要在中获取last_insert_row和使用它insert

我发现了一些有关绑定的信息,但是我并没有完全理解它。


7
sqlite不支持此功能。
Dan D.

2
希望现在有更好的解决方案-2018
MarshallMa

Answers:


92

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;

这些[]括号用于做什么?
WindRider 2013年

1
@WindRider:避免与保留字冲突。有我的习惯,但在这种情况下是不必要的,因此将其删除。
Herman Schoenfeld

2
这行得通,但有几点建议,我在spacespaceite上尝试过,并说不能在事务内更改临时存储。另外,我认为您在开始后就缺少分号。共享此解决方案的Tx。
Glenn Plas 2013年

如何增加这个?我的意思是如何增加此变量,就好像它随着顺序调用而增加一样。
Vibhu Jain

2
临时表不能保证在内存中。这取决于编译器选项以及PRAGMA temp_store设置。实际上,根据在线文档默认设置是将临时文件存储到磁盘(包括用于临时表和索引的文件)。
C Perkins

43

Herman的解决方案有效,但是可以简化,因为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';

3
但是如果您想在比较中使用它,则不要忘记将值转换为正确的类型,否则可能会得到令人惊讶的结果
vlad_tepesch

26

对于只读变量(即,一次设置并在查询中任何地方使用的常量值),请使用公用表表达式(CTE)。

WITH const AS (SELECT 'name' AS name, 10 AS more)
SELECT table.cost, (table.cost + const.more) AS newCost
FROM table, const 
WHERE table.name = const.name

SQLite WITH子句


1
这是imo的最优雅答案
Vladtn

这是我一直在寻找的答案类型。
John Baber-Lucero

9

赫尔曼的解决方案对我有用,但是...让我有些困惑。根据他的回答,我将包括我自己制作的演示。我的答案中的其他功能包括外键支持,自动递增键,以及使用该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

尝试使用绑定值。您不能像在T-SQL中那样使用变量,但可以使用“参数”。我希望以下链接有用。绑定值


26
您可以通过提供示例来丰富您的答案。链接可以移动,但您的示例将在此处供将来参考。
Pabluez 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.