在sqlite中声明变量并使用它

Muh*_*our 85 sql sqlite variables declaration

我想在sqlite中声明一个变量并在插入操作中使用它

就像在MS SQL中一样

declare @name as varchar(10)
set name = 'name'
select * from table where name = @name
Run Code Online (Sandbox Code Playgroud)

例如,我需要获取last_insert_row并在插入中使用它

我找到了一些关于绑定的东西,但我并没有完全理解它

Her*_*eld 88

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;
Run Code Online (Sandbox Code Playgroud)

  • 临时表不保证在内存中*。这取决于编译器选项以及`PRAGMA temp_store` 设置。事实上,根据[在线文档](https://www.sqlite.org/tempfiles.html#the_sqlite_temp_store_compile_time_parameter_and_pragma),**默认设置是将临时文件存储到磁盘**(包括临时表和索引的文件)。 (4认同)
  • 这行得通,但有几点建议,我在spacespaceite上尝试过,并说不能在事务内更改临时存储。另外,我认为您在开始后就缺少分号。共享此解决方案的Tx。 (2认同)

ste*_*nci 42

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';
Run Code Online (Sandbox Code Playgroud)

  • 但如果要在比较中使用它,则不要忘记将值转换为正确的类型,否则可能会得到令人惊讶的结果 (2认同)

Ste*_*ugi 10

要在您的示例中使用 denverCR 中的一个:

WITH tblCTE AS (SELECT "Joe" AS namevar)
SELECT * FROM table, tblCTE
WHERE name = namevar
Run Code Online (Sandbox Code Playgroud)

作为初学者,我发现其他答案太难以理解,希望这有效


Thi*_*ark 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;
Run Code Online (Sandbox Code Playgroud)


Den*_*rCR 5

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

WITH const AS (SELECT 'name' AS name, 10 AS more)
SELECT *, (table.cost + const.more) AS newCost
FROM table, const 
WHERE table.name = const.name
Run Code Online (Sandbox Code Playgroud)

SQLite WITH子句

  • 我认为这是最优雅的答案 (9认同)
  • 这就是我一直在寻找的答案类型。 (5认同)