SQLite에서 변수를 선언하고 사용


94

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
더 나은 솔루션은 이제 거기에 희망 - 8 월 2018 년
MarshallMa

답변:


93

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 2013 년

2
이것은 작동하지만 몇 가지 발언이 있습니다. 나는이 작업을 spatialite에서 시도했으며 트랜잭션 내에서 임시 저장소를 변경할 수 없다고 말합니다. 또한 BEGIN 뒤에 세미콜론이 누락되었다고 생각합니다. 이 솔루션을 공유하기위한 Tx.
Glenn Plas

이것을 증가시키는 방법? 순차 호출로 증가하는 것처럼이 변수를 증가시키는 방법을 의미합니다.
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

33

읽기 전용 변수 (즉, 한 번 설정되고 쿼리의 모든 위치에서 사용되는 상수 값)의 경우 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 절


2
이것은 가장 우아한 대답입니다 imo
Vladtn

1
이것이 제가 찾고 있던 답변의 유형입니다.
John Baber-Lucero

9

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;

좋은 예를 들어 주셔서 감사합니다. 의견과 링크가 훨씬 더 유용합니다
splaisan

-1

바인딩 값을 사용해보십시오. T-SQL에서와 같이 변수를 사용할 수 없지만 "매개 변수"는 사용할 수 있습니다. 다음 링크가 유용하기를 바랍니다. 바인딩 값


26
예를 들어 답변을 풍부하게 만들 수 있습니다. 링크를 이동할 수 있지만 나중에 참조 할 수 있도록 예제가 여기에 있습니다.
Pabluez
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.