ประกาศตัวแปรใน SQLite และใช้งาน


94

ฉันต้องการประกาศตัวแปรใน SQLite และใช้ในinsertการดำเนินการ

เช่นเดียวกับใน MS SQL:

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

ตัวอย่างเช่นผมจะต้องได้รับและใช้ในlast_insert_rowinsert

ฉันพบบางอย่างเกี่ยวกับการผูกมัด แต่ฉันไม่เข้าใจมันจริงๆ


7
sqlite ไม่รองรับสิ่งนี้
Dan D.

2
หวังว่าจะมีทางออกที่ดีกว่าตอนนี้ - ส.ค. 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

1
@WindRider: เพื่อหลีกเลี่ยงการปะทะกับคำสงวน นิสัยของฉัน แต่ไม่จำเป็นในกรณีนี้จึงถูกลบออก
Herman Schoenfeld

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

สำหรับตัวแปรแบบอ่านอย่างเดียว (นั่นคือค่าคงที่ตั้งครั้งเดียวและใช้ที่ใดก็ได้ในแบบสอบถาม) ให้ใช้ 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 กับอนุประโยค


2
นี่คือคำตอบที่สง่างามที่สุด imo
Vladtn

1
นี่คือประเภทของคำตอบที่ฉันกำลังมองหา
John Baber-Lucero

9

วิธีแก้ปัญหาของเฮอร์แมนใช้ได้ผลสำหรับฉัน แต่...ฉันก็สับสนเล็กน้อย ฉันรวมการสาธิตที่ฉันคิดขึ้นจากคำตอบของเขา คุณสมบัติเพิ่มเติมในคำตอบของฉัน ได้แก่ การรองรับคีย์ต่างประเทศการเพิ่มคีย์อัตโนมัติและการใช้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

0

ฉันพบวิธีแก้ปัญหาหนึ่งในการกำหนดตัวแปรให้กับ 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 และ double quotes และระหว่างเครื่องหมายคำพูดคู่และ LIKE


-1

ลองใช้ Binding Values คุณไม่สามารถใช้ตัวแปรได้เหมือนกับที่คุณทำใน T-SQL แต่คุณสามารถใช้ "พารามิเตอร์" ได้ ฉันหวังว่าลิงค์ต่อไปนี้จะมีประโยชน์ ค่าผูกมัด


26
คุณสามารถทำให้คำตอบของคุณสมบูรณ์ยิ่งขึ้นด้วยตัวอย่าง สามารถย้ายลิงก์ได้ แต่ตัวอย่างของคุณจะอยู่ที่นี่เพื่อใช้อ้างอิงในอนาคต
Pabluez
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.