在 SQLite 中声明变量并使用它

发布于 2024-12-09 19:57:55 字数 302 浏览 4 评论 0原文

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

就像在 MS SQL 中一样:

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

例如,我需要获取 last_insert_row 并在 insert 中使用它。

我发现了一些关于绑定的东西,但我并没有真正完全理解它。

I want to declare a variable in SQLite and use it in insert operation.

Like in MS SQL:

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

For example, I will need to get last_insert_row and use it in insert.

I have found something about binding but I didn't really fully understood it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

谁的年少不轻狂 2024-12-16 19:57:55

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;

SQLite doesn't support native variable syntax, but you can achieve virtually the same using an in-memory temp table.

I've used the below approach for large projects and works like a charm.

    /* 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;
热血少△年 2024-12-16 19:57:55

对于只读变量(即设置一次并在查询中的任何位置使用的常量值),请使用公共表表达式 (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 子句

For a read-only variable (that is, a constant value set once and used anywhere in the query), use a Common Table Expression (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

深爱成瘾 2024-12-16 19:57:55

Herman 的解决方案有效,但可以简化,因为 Sqlite 允许在任何字段上存储任何值类型。

下面是一个更简单的版本,它使用一个声明为 TEXTValue 字段来存储任何值:

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';

Herman's solution works, but it can be simplified because Sqlite allows to store any value type on any field.

Here is a simpler version that uses one Value field declared as TEXT to store any 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';
幸福丶如此 2024-12-16 19:57:55

在您的示例中使用 denverCR 的答案:

WITH tblCTE AS (SELECT "Joe" AS namevar)
SELECT * FROM table, tblCTE
WHERE name = namevar

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

To use the one from denverCR in your example:

WITH tblCTE AS (SELECT "Joe" AS namevar)
SELECT * FROM table, tblCTE
WHERE name = namevar

As a beginner I found other answers too difficult to understand, hope this works

千纸鹤 2024-12-16 19:57:55

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

Herman's solution worked for me, but the ... had me mixed up for a bit. I'm including the demo I worked up based on his answer. The additional features in my answer include foreign key support, auto incrementing keys, and use of the last_insert_rowid() function to get the last auto generated key in a transaction.

My need for this information came up when I hit a transaction that required three foreign keys but I could only get the last one with 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;
栖迟 2024-12-16 19:57:55

创建“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

Creating "VARIABLE" for use in SQLite SELECT (and some other) statements

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
一口甜 2024-12-16 19:57:55

阅读完所有答案后,我更喜欢这样的内容:

select *
from table, (select 'name' as name) const
where table.name = const.name

After reading all the answers I prefer something like this:

select *
from table, (select 'name' as name) const
where table.name = const.name
清风夜微凉 2024-12-16 19:57:55

我经常需要对数据库中的案例进行事后分析。这涉及到运行一系列针对该组值进行过滤的查询,每次使用一组不同的值。

我发现拥有一个“变量表”非常有用,每个“变量”需要一列,我每次都设置我需要的值,并且一系列查询不会每次都改变。

PRAGMA temp_store = 2;      -- store temp table in memory, not on disk
CREATE TEMP TABLE IF NOT EXISTS _vars (_var1 INTEGER, _var2 INTEGER);

DELETE FROM _vars WHERE TRUE;       -- run this when changing set of values
INSERT OR REPLACE INTO  _vars VALUES (1492, 1112);       --new values
SELECT * FROM _vars;       -- check values are set and only one row is present

-- here comes the series of queries I need to run for each set of values
SELECT * 
FROM my_table_name  
WHERE one_column_name = (SELECT _var1 FROM _vars)
  AND other_column_name = (SELECT _var2 FROM _vars);

如果您确保您的“变量”具有唯一的名称(该名称不会出现在您正在查询的表中),您可以进一步简化查询:

SELECT * 
FROM my_table_name, _vars
WHERE one_column_name = _var1
  AND other_column_name = _var2;

当我完成一组值时,我将返回到DELETE 并为我的“变量”设置一组新值并继续。

最后,通过

DROP TABLE IF EXISTS _vars;

警告

进行清理。请记住,所有这些都是在 PRAGMA temp_store = 2; 生效时进行的,因此任何数据创建都将尝试在内存中进行。

还要注意数据库/连接的更改。在内存中创建的表与活动数据库或连接耦合。如果您更改数据库(认为“USE”)或在数据库编辑器/GUI 中更改连接,内存中的时态表将不会遵循:您将必须为下一个数据库或连接再次创建它们。这意味着,如果您要更改数据库以比较来自多个数据库的查询结果,请记住您的查询正在使用内存中当前关联的表中的值与您正在使用的数据库。因此,如果您将它们更改为在一个数据库中运行查询,然后更改为在另一个数据库中运行相同的查询,则需要在运行查询之前更改内存中的值,否则将不会运行相同的查询。

I frequently have to post-mortem analyse cases in a database. This involves running a series of queries filtering for the set of values, several times with a different set of values each time.

I found very useful to have a "variables table" with one column per "variable" needed, where I set the values I need each time, and having the series of queries not change every time.

PRAGMA temp_store = 2;      -- store temp table in memory, not on disk
CREATE TEMP TABLE IF NOT EXISTS _vars (_var1 INTEGER, _var2 INTEGER);

DELETE FROM _vars WHERE TRUE;       -- run this when changing set of values
INSERT OR REPLACE INTO  _vars VALUES (1492, 1112);       --new values
SELECT * FROM _vars;       -- check values are set and only one row is present

-- here comes the series of queries I need to run for each set of values
SELECT * 
FROM my_table_name  
WHERE one_column_name = (SELECT _var1 FROM _vars)
  AND other_column_name = (SELECT _var2 FROM _vars);

If you ensure your "variables" have unique names (that do not occur in the tables you are querying), you may simplify even more the queries:

SELECT * 
FROM my_table_name, _vars
WHERE one_column_name = _var1
  AND other_column_name = _var2;

When I finish with one set of values I go back to the DELETE and set a new set of values for my "variables" and keep going.

At the end, clean up by means of

DROP TABLE IF EXISTS _vars;

WARNING

Keep in mind that all of this is made while PRAGMA temp_store = 2; is in force, so any data creation will try to go on memory.

Also beware of database/connection changes. The tables created in memory are coupled with the active database or connection. If you change database (think "USE ") or in you database editor/GUI you change connection, the temporal tables in memory will not follow: you will have to create them again for the next database or connection. And that implies that if you are changing database to compare query results from more than one database, keep in mind that your queries are using the values from the tables in memory currently associated with the database you are using. It follows that if you change them to run a query in one database and then you change to run the same query in another database, you need change the values in memory before running the query or you will not be running the same query.

听,心雨的声音 2024-12-16 19:57:55

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

Try using Binding Values. You cannot use variables as you do in T-SQL but you can use "parameters". I hope the following link is usefull.Binding Values

神回复 2024-12-16 19:57:55

我找到了一种将变量分配给 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 之间

I found one solution for assign variables to COLUMN or 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,))

Don't forget input one space between the WHERE and double quotes
and between the double quotes and LIKE

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文