在 SQLite 中声明变量并使用它
Posted
技术标签:
【中文标题】在 SQLite 中声明变量并使用它【英文标题】:Declare variable in SQLite and use it 【发布时间】:2011-12-06 01:39:32 【问题描述】:我想在 SQLite 中声明一个变量,并在insert
操作中使用它。
就像在 MS SQL 中一样:
declare @name as varchar(10)
set name = 'name'
select * from table where name = @name
例如,我需要获取last_insert_row
并在insert
中使用它。
我发现了一些关于绑定的东西,但我并没有完全理解它。
【问题讨论】:
sqlite 不支持这个。 希望现在有更好的解决方案 - 2018 年 8 月 【参考方案1】:尝试使用绑定值。您不能像在 T-SQL 中那样使用变量,但可以使用“参数”。我希望以下链接有用。Binding Values
【讨论】:
您可以通过提供示例使您的答案更丰富。链接可以移动,但您的示例将在这里供将来参考。【参考方案2】:SQLite 不支持本机变量语法,但您可以使用内存中的临时表实现几乎相同的效果。
我在大型项目中使用了以下方法,效果很好。
/* Create in-memory temp table for variables */
BEGIN;
PRAGMA temp_store = 2; /* 2 means use in-memory */
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:避免与保留字发生任何冲突。我的一个习惯,但在这种情况下是不必要的,所以它们被删除了。 这行得通,但有几点说明,我在 spatialite 上试过,它说你不能从事务中更改临时存储。另外,我认为您在 BEGIN 之后缺少分号。 Tx 分享此解决方案。 如何增加这个?我的意思是如何增加这个变量,就好像它随着顺序调用而增加一样。 临时表不保证在内存中。这取决于编译器选项以及PRAGMA temp_store
设置。事实上,根据online docs,默认设置是将临时文件存储到磁盘(包括临时表和索引的文件)。【参考方案3】:
Herman 的解决方案有效,但可以简化,因为 Sqlite 允许在任何字段上存储任何值类型。
这是一个更简单的版本,它使用一个声明为 TEXT
的 Value
字段来存储任何值:
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';
【讨论】:
但是如果你想在比较中使用它,你不应该忘记将值转换为正确的类型,否则你可能会得到令人惊讶的结果【参考方案4】:Herman 的解决方案对我有用,但 ...
让我有点困惑。我包括根据他的回答制作的演示。我的回答中的其他功能包括外键支持、自动递增键以及使用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;
【讨论】:
【参考方案5】:对于只读变量(即设置一次并在查询中的任何位置使用的常量值),请使用公用表表达式 (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 clause
【讨论】:
这是我最优雅的答案【参考方案6】:我找到了一种将变量分配给 COLUMN 或 TABLE 的解决方案:
conn = sqlite3.connect('database.db')
cursor=conn.cursor()
z="Cash_payers" # bring results from Table 1 , Column: Customers and COLUMN
# which are pays cash
sorgu_y= Customers #Column name
query1="SELECT * FROM Table_1 WHERE " +sorgu_y+ " LIKE ? "
print (query1)
query=(query1)
cursor.execute(query,(z,))
不要忘记在 WHERE 和双引号之间输入一个空格 以及在双引号和 LIKE 之间
【讨论】:
【参考方案7】:创建“VARIABLE”以在 SQLite SELECT(和其他一些)语句中使用
CREATE TEMP TABLE IF NOT EXISTS variable AS SELECT '2002' AS _year; --creating the "variable" named "_year" with value "2002"
UPDATE variable SET _year = '2021'; --changing the variable named "_year" assigning "new" value "2021"
SELECT _year FROM variable; --viewing the variable
SELECT 'TEST', (SELECT _year FROM variable) AS _year; --using the variable
SELECT taxyr FROM owndat WHERE taxyr = (SELECT _year FROM variable); --another example of using the variable
SELECT DISTINCT taxyr FROM owndat WHERE taxyr IN ('2022',(SELECT _year FROM variable)); --another example of using the variable
DROP TABLE IF EXISTS variable; --releasing the "variable" if needed to be released
【讨论】:
【参考方案8】:在您的示例中使用来自 denverCR 的那个:
WITH tblCTE AS (SELECT "Joe" AS namevar)
SELECT * FROM table, tblCTE
WHERE name = namevar
作为一个初学者,我发现其他答案太难理解了,希望这可行
【讨论】:
以上是关于在 SQLite 中声明变量并使用它的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 中插入 datetime.now SQLite
为什么在迭代sqlite数据库时for-loop变量会跳过每隔一行?