Deklarasikan variabel di SQLite dan gunakan itu

94

Saya ingin mendeklarasikan variabel di SQLite dan menggunakannya dalam insertoperasi.

Seperti di MS SQL:

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

Misalnya, saya perlu mendapatkan last_insert_rowdan menggunakannya di insert.

Saya telah menemukan sesuatu tentang mengikat tetapi saya tidak sepenuhnya memahaminya.

Muhammad Nour
sumber
7
sqlite tidak mendukung ini.
Dan D.
2
berharap ada solusi yang lebih baik sekarang - Agt 2018
MarshallMa

Jawaban:

93

SQLite tidak mendukung sintaks variabel native, tetapi Anda dapat mencapai hal yang hampir sama menggunakan tabel temp dalam memori.

Saya telah menggunakan pendekatan di bawah ini untuk proyek besar dan bekerja seperti pesona.

    /* 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 Schoenfeld
sumber
Untuk apa tanda kurung [] ini digunakan?
WindRider
1
@WindRider: untuk menghindari bentrokan dengan kata-kata khusus. Kebiasaan saya tetapi tidak perlu dalam kasus ini, jadi mereka dihapus.
Herman Schoenfeld
2
Ini berfungsi tetapi ada beberapa komentar, saya mencoba ini di spatialite, dan di sana dikatakan Anda tidak dapat mengubah penyimpanan sementara dari dalam transaksi. Juga, saya pikir Anda kehilangan titik koma setelah BEGIN. Tx untuk membagikan solusi ini.
Glenn Plas
Bagaimana cara meningkatkan ini? Maksud saya bagaimana menaikkan variabel ini seolah-olah bertambah dengan panggilan berurutan.
Vibhu Jain
2
Tabel sementara tidak dijamin berada di memori . Itu tergantung pada opsi kompilator dan juga PRAGMA temp_storepengaturannya. Faktanya, menurut dokumen online , pengaturan default adalah menyimpan file sementara ke disk (yang mencakup file untuk tabel dan indeks sementara).
C Perkins
43

Solusi Herman berfungsi, tetapi dapat disederhanakan karena Sqlite memungkinkan untuk menyimpan jenis nilai apa pun di bidang apa pun.

Berikut adalah versi sederhana yang menggunakan satu Valuebidang yang dideklarasikan TEXTuntuk menyimpan nilai apa pun:

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';
stenci
sumber
3
tetapi Anda tidak boleh lupa untuk memasukkan nilai ke tipe yang tepat jika Anda ingin menggunakannya dalam perbandingan atau Anda mungkin mendapatkan hasil yang mengejutkan
vlad_tepesch
33

Untuk variabel hanya baca (yaitu, nilai konstanta yang ditetapkan sekali dan digunakan di mana saja dalam kueri), gunakan 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 DENGAN klausa

DenverCR
sumber
2
Ini adalah jawaban paling elegan imo
Vladtn
1
Ini adalah jenis jawaban yang saya cari.
John Baber-Lucero
9

Solusi Herman berhasil untuk saya, tetapi ...saya sedikit bingung. Saya termasuk demo yang saya kerjakan berdasarkan jawabannya. Fitur tambahan dalam jawaban saya termasuk dukungan kunci asing, kunci kenaikan otomatis, dan penggunaan last_insert_rowid()fungsi untuk mendapatkan kunci yang dibuat otomatis terakhir dalam sebuah transaksi.

Kebutuhan saya akan informasi ini muncul ketika saya mencapai transaksi yang membutuhkan tiga kunci asing tetapi saya hanya bisa mendapatkan yang terakhir dengan 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;
ThisClark
sumber
terima kasih untuk contoh yang bagus, memang jauh lebih berguna bahwa opini dan tautan
splaisan
-1

Coba gunakan Binding Values. Anda tidak dapat menggunakan variabel seperti yang Anda lakukan di T-SQL tetapi Anda dapat menggunakan "parameter". Semoga link berikut bermanfaat. Nilai-Nilai yang Mengikat

Tidak dikenal
sumber
26
Anda dapat membuat jawaban Anda lebih kaya dengan memberikan contoh. Tautan dapat dipindahkan tetapi contoh Anda akan ada di sini untuk referensi di masa mendatang.
Pabluez