SQLite에서 변수를 선언하고 insert
작동에 사용하고 싶습니다 .
MS SQL에서와 같이 :
declare @name as varchar(10)
set name = 'name'
select * from table where name = @name
예를 들어에서 가져 와서 last_insert_row
사용해야합니다 insert
.
바인딩에 대해 뭔가를 찾았지만 완전히 이해하지 못했습니다.
답변
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;
답변
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';
답변
읽기 전용 변수 (즉, 한 번 설정되고 쿼리의 모든 위치에서 사용되는 상수 값)의 경우 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
답변
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;