SQLite ALTER TABLE
. के बहुत सीमित उपसमुच्चय का समर्थन करता है बयान। केवल वही चीज़ें जो आप ALTER TABLE
. के साथ कर सकते हैं SQLite में एक तालिका का नाम बदलें, किसी तालिका के भीतर एक स्तंभ का नाम बदलें, या किसी मौजूदा तालिका में एक नया स्तंभ जोड़ें।
दूसरे शब्दों में, आप ALTER TABLE
. का उपयोग नहीं कर सकते हैं मौजूदा तालिका में एक विदेशी कुंजी जोड़ने के लिए जैसे आप अन्य डेटाबेस प्रबंधन प्रणालियों में कर सकते हैं।
इसलिए, SQLite में किसी मौजूदा तालिका में एक विदेशी कुंजी को "जोड़ने" का एकमात्र तरीका एक विदेशी कुंजी के साथ एक नई तालिका बनाना है, फिर डेटा को नई तालिका में स्थानांतरित करना है।
ऐसा करने के एक से अधिक तरीके हैं, लेकिन एक अनुशंसित तरीका है।
अनुशंसित तरीका
SQLite दस्तावेज़ीकरण तालिका में स्कीमा परिवर्तन करने के लिए 12 चरणों वाली प्रक्रिया की अनुशंसा करता है।
इस लेख के प्रयोजनों के लिए, हम केवल एक विदेशी कुंजी जोड़ने से निपटेंगे।
इसे कुछ हद तक यथार्थवादी बनाने के लिए, हम सुनिश्चित करेंगे कि तालिका में पहले से ही डेटा है।
विदेशी कुंजी के बिना मूल तालिका
सबसे पहले, आइए एक टेबल बनाएं बिना एक विदेशी कुंजी और इसे डेटा के साथ पॉप्युलेट करें।
CREATE TABLE Types(
TypeId INTEGER PRIMARY KEY,
Type
);
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId
);
INSERT INTO Types VALUES
( NULL, 'Dog' ),
( NULL, 'Cat' ),
( NULL, 'Parakeet' ),
( NULL, 'Hamster' );
INSERT INTO Pets VALUES
( NULL, 'Brush', 3 ),
( NULL, 'Tweet', 3 ),
( NULL, 'Yelp', 1 ),
( NULL, 'Woofer', 1 ),
( NULL, 'Fluff', 2 );
दरअसल, यहां मैंने दो टेबल बनाए और उन्हें डेटा से भर दिया। दो टेबल, क्योंकि एक (प्रकार ) में प्राथमिक कुंजी होगी और दूसरी (पालतू जानवर .) ) में विदेशी कुंजी होगी।
ध्यान दें कि मैंने कोई विदेशी कुंजी नहीं बनाई है।
हम निम्न आदेश चलाकर सत्यापित कर सकते हैं कि कोई विदेशी कुंजी नहीं है:
PRAGMA foreign_key_list(Pets);
मेरे मामले में, मुझे निम्नलिखित परिणाम मिलते हैं:
(यह खाली है क्योंकि इस टेबल पर कोई विदेशी कुंजी बाधा नहीं है।)
आइए अब एक विदेशी कुंजी "जोड़ें"।
विदेशी कुंजी जोड़ें
निम्न कोड एक विदेशी कुंजी बाधा के साथ एक नई तालिका बनाकर, उस तालिका में डेटा स्थानांतरित करके, मूल तालिका को छोड़ कर, फिर नई तालिका का नाम बदलकर मूल तालिका के नाम पर बदलकर हमारी तालिका में एक विदेशी कुंजी जोड़ता है।
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
CREATE TABLE Pets_new(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
INSERT INTO Pets_new SELECT * FROM Pets;
DROP TABLE Pets;
ALTER TABLE Pets_new RENAME TO Pets;
COMMIT;
PRAGMA foreign_keys = ON;
हो गया।
अगर आपको किसी इंडेक्स, ट्रिगर या व्यू को फिर से बनाना है, तो ALTER TABLE
के बाद ऐसा करें कथन जो तालिका का नाम बदलता है (COMMIT
. से ठीक पहले )
आइए अब फिर से विदेशी कुंजी बाधाओं के लिए तालिका देखें।
.mode line
PRAGMA foreign_key_list(Pets);
परिणाम (ऊर्ध्वाधर आउटपुट का उपयोग करके):
id = 0 seq = 0 table = Types from = TypeId to = TypeId on_update = NO ACTION on_delete = NO ACTION match = NONE
इस बार हम विदेशी कुंजी बाधा का विवरण देख सकते हैं।
ध्यान दें कि मेरे आदेश की पहली पंक्ति (.mode line
) का विदेशी कुंजी बनाने से कोई लेना-देना नहीं है। मैंने इसे पूरी तरह से मेरे टर्मिनल के परिणाम को बदलने के तरीके को बदलने के लिए रखा है (ताकि आपको परिणाम देखने के लिए बग़ल में स्क्रॉल न करना पड़े)।
एक वैकल्पिक तरीका
पिछले उदाहरण को देखते हुए, आप सोच रहे होंगे कि ऐसा करने का एक अधिक कुशल तरीका है। उदाहरण के लिए आप इसे इस तरह कर सकते हैं:
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
ALTER TABLE Pets RENAME TO Pets_old;
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
INSERT INTO Pets SELECT * FROM Pets_old;
DROP TABLE Pets_old;
COMMIT;
PRAGMA foreign_keys = ON;
और यह सच है। मेरे उदाहरण के साथ, यह विधि ठीक वैसे ही काम करती है।
लेकिन इस पद्धति में किसी भी मौजूदा ट्रिगर, दृश्य और विदेशी कुंजी बाधाओं में तालिका के संदर्भों को भ्रष्ट करने की क्षमता है।
इसलिए यदि आपकी तालिका में पहले से ही मौजूदा ट्रिगर, दृश्य या विदेशी कुंजी बाधाएं हैं, तो संभवतः अनुशंसित विधि का उपयोग करना अधिक सुरक्षित है।