Değişkeni SQLite'da bildirin ve kullanın


94

SQLite'da bir değişken tanımlayıp insertoperasyonda kullanmak istiyorum .

MS SQL'deki gibi:

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

Örneğin, onu almam last_insert_rowve kullanmam gerekecek insert.

Bağlama ile ilgili bir şey buldum ama tam olarak anlamadım.


7
sqlite bunu desteklemiyor.
Dan D.

2
umarım şimdi daha iyi bir çözüm vardır - Ağu 2018
MarshallMa

Yanıtlar:


93

SQLite yerel değişken sözdizimini desteklemez, ancak bellek içi geçici tablo kullanarak hemen hemen aynısını elde edebilirsiniz.

Büyük projeler için aşağıdaki yaklaşımı kullandım ve bir cazibe gibi çalışıyor.

    /* 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;

Bu [] parantezler ne için kullanılıyor?
WindRider

1
@WindRider: ayrılmış sözcüklerle herhangi bir çatışmayı önlemek için. Benim bir alışkanlığım ama bu durumda gereksiz, bu yüzden ortadan kalkıyorlar.
Herman Schoenfeld

2
Bu işe yarıyor ama birkaç açıklama var, bunu spatialite üzerinde denedim ve orada geçici depoyu bir işlem içinden değiştiremeyeceğinizi söylüyor. Ayrıca, BEGIN'den sonra noktalı virgül eksik olduğunu düşünüyorum. Bu çözümü paylaşmak için Tx.
Glenn Plas

Bunu nasıl artırabilirim? Bu değişkenin sıralı çağrılarla artıyor gibi nasıl artırılacağını kastediyorum.
Vibhu Jain

2
Geçici tabloların bellek içi olması garanti edilmez . Bu, derleyici seçeneklerine ve PRAGMA temp_storeayara bağlıdır. Aslında, çevrimiçi belgelere göre , varsayılan ayar dosyaları geçici olarak diske depolamaktır (geçici tablolar ve dizinler için dosyalar içerir).
C Perkins

43

Herman'ın çözümü işe yarıyor, ancak Sqlite herhangi bir alanda herhangi bir değer türünü depolamaya izin verdiği için basitleştirilebilir.

Burada, herhangi bir değeri depolamak için Valuebildirilen bir alanı kullanan daha basit bir sürüm 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
ancak karşılaştırmalarda kullanmak istiyorsanız değeri doğru türe
çevirmeyi unutmamalısınız, aksi

33

Salt okunur bir değişken için (yani, bir kez ayarlanan ve sorgunun herhangi bir yerinde kullanılan sabit bir değer), bir Ortak Tablo İfadesi (CTE) kullanın.

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 yan tümcesi


2
Bu en zarif cevap imo
Vladtn

1
Bu, aradığım cevap türü.
John Baber-Lucero

9

Herman'ın çözümü benim için çalıştı, ancak ...beni biraz karıştırdı. Cevabına göre hazırladığım demoyu ekliyorum. Cevabımdaki ek özellikler arasında yabancı anahtar desteği, otomatik artan anahtarlar ve last_insert_rowid()bir işlemde otomatik olarak oluşturulan son anahtarı almak için işlevin kullanılması yer alıyor .

Bu bilgiye ihtiyacım üç yabancı anahtar gerektiren bir işleme bastığımda ortaya çıktı, ancak yalnızca sonuncusunu alabildim 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;

güzel örnek için teşekkürler, gerçekten çok daha faydalı olan görüşler ve bağlantılar
splaisan

-1

Bağlama Değerlerini kullanmayı deneyin. Değişkenleri T-SQL'de olduğu gibi kullanamazsınız ancak "parametreler" kullanabilirsiniz. Umarım aşağıdaki bağlantı yararlıdır. Bağlayıcı Değerler


26
Örnekler sunarak yanıtınızı daha zengin hale getirebilirsiniz. Bağlantılar taşınabilir ancak örnekleriniz ileride başvurmak için burada olacaktır.
Pabluez
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.