كيف يمكنني إعادة تسمية عمود في قاعدة بيانات SQLite الطاولة ؟

StackOverflow https://stackoverflow.com/questions/805363

  •  03-07-2019
  •  | 
  •  

سؤال

وأود أن تحتاج إلى إعادة تسمية عدد قليل من الأعمدة في بعض الجداول في قاعدة بيانات SQLite.أعلم أن مثل هذا السؤال وقد طلب على ستاكوفيرفلوو سابقا ، ولكن كان SQL بشكل عام ، وفي حالة سكليتي لم يذكر.

من سكليتي وثائق تغيير الجدول, أستنتج أن ليس من الممكن أن تفعل مثل هذا الشيء "بسهولة" (أيواحد يغير الجدول البيان).

كنت أتساءل شخص يعرف من عام SQL طريقة من يفعل مثل هذا الشيء مع SQLite.

هل كانت مفيدة؟

المحلول

هذا كان مجرد ثابتة مع 2018-09-15 (3.25.0)

التحسينات ALTER TABLE الأمر:

  • إضافة دعم إعادة تسمية الأعمدة في جدول باستخدام ALTER TABLE الجدول RENAME COLUMN oldname TO newname.
  • إصلاح الجدول تسمية ميزة بحيث يستكمل أيضا إشارات إلى إعادة تسمية الجدول في مشغلات وجهات النظر.

يمكنك العثور على جملة جديدة موثقة تحت ALTER TABLE

على RENAME COLUMN TO جملة التغيرات في العمود اسم الجدول الجدول-في الجديد-عمود-اسم.اسم العمود هو تغيير داخل تعريف الجدول نفسه أيضا في جميع الفهارس, مشغلات, و وجهات النظر التي تشير إلى عمود.إذا كان اسم العمود تغيير من شأنه أن يؤدي الغموض الدلالي في مشغل أو عرض ، ثم RENAME COLUMN فشل مع خطأ و لا يتم تطبيق التغييرات.

enter image description here مصدر الصورة: https://www.sqlite.org/images/syntax/alter-table-stmt.gif

على سبيل المثال:

CREATE TABLE tab AS VALUES(1);

SELECT * FROM tab;

ALTER TABLE tab RENAME TO tab_new;

SELECT * FROM tab_new;

db-fiddle.com demo


دعم الروبوت

كما من الكتابة ، الروبوت API 27 يستخدم سكليتي إصدار حزمة 3.19.

استنادا إلى الإصدار الحالي أن الروبوت هو أن هذا التحديث قادم في النسخة 3.25.0 سكليتي, وأود أن أقول أن لديك قليلا من الانتظار (حوالي API 33) قبل دعم هذا إضافة إلى الروبوت.

و حتى ذلك الحين, إذا كنت بحاجة إلى دعم أي إصدارات أقدم من API 33, سوف لا تكون قادرة على استخدام هذا.

نصائح أخرى

ويقول لديك جدول وتحتاج إلى إعادة تسمية "colb" إلى "col_b":

أولا إعادة تسمية الجدول القديم:

ALTER TABLE orig_table_name RENAME TO tmp_table_name;

وثم إنشاء الجدول الجديد، استنادا إلى الجدول القديم ولكن مع اسم العمود تحديث:

CREATE TABLE orig_table_name (
  col_a INT
, col_b INT
);

وثم نسخ محتويات على الجانب الآخر من الجدول الأصلي.

INSERT INTO orig_table_name(col_a, col_b)
SELECT col_a, colb
FROM tmp_table_name;

وأخيرا، إسقاط الجدول القديم.

DROP TABLE tmp_table_name;

والتفاف كل هذا في BEGIN TRANSACTION; وCOMMIT; هو أيضا ربما يكون فكرة جيدة.

ولئن كان صحيحا أنه لا يوجد أي تغيير العمود ، إذا كنت تريد فقط إعادة تسمية عمود إسقاط قيد NOT NULL, أو تغيير نوع البيانات ، يمكنك استخدام ما يلي مجموعة من الأوامر:

ملاحظة:هذه الأوامر لديها القدرة على الفاسدين قاعدة البيانات الخاصة بك, لذا تأكد من أن لديك نسخة احتياطية

PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;

سوف تحتاج إما إلى إغلاق ثم إعادة فتح الاتصال الخاص بك أو فراغ قاعدة البيانات لتحديث التغييرات في المخطط.

على سبيل المثال:

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT NULL);  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
Error: BOOKS.publication_date may not be NULL  
sqlite> PRAGMA writable_schema = 1; 
sqlite> UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';  
sqlite> PRAGMA writable_schema = 0;  
sqlite> .q  

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
sqlite> .q  

المراجع اتبع:


pragma writable_schema
عند هذا pragma ، SQLITE_MASTER الجداول في قاعدة البيانات التي يمكن تغييرها باستخدام العادية تحديث إدراج وحذف البيانات.تحذير:سوء استخدام هذه pragma يمكن أن يؤدي بسهولة في الفاسدة ملف قاعدة البيانات.

تغيير الجدول
سكليتي يدعم مجموعة فرعية محدودة من ALTER TABLE.الأمر ALTER TABLE في SQLite يسمح للمستخدم إعادة تسمية الجدول أو إضافة عمود جديد إلى جدول موجود.فإنه ليس من الممكن إعادة تسمية عمود إزالة عمود ، أو إضافة أو إزالة القيود من الجدول.

ALTER TABLE SYNTAX

وحفر حولها، ولقد وجدت هذه المتعدد (لينكس | ماك | نوافذ) أداة رسومية دعا DB لسكليتي أن الواقع يسمح احد لإعادة تسمية الأعمدة بطريقة سهلة الاستعمال جدا!

وتحرير | تعديل الجدول | حدد الجدول | تحرير الميدان. صوت نقر! فويلا!

ولكن، إذا كان شخص يريد أن تشترك في طريقة برمجية للقيام بذلك، وسأكون سعيدا لمعرفة!

مؤخرا كان لي أن تفعل ذلك في SQLite3 مع طاولة اسمه نقاط مع colunms id, لون, اللات.Erroneusly عندما كان الجدول المستوردة ، قيم الحرية حيث المخزنة في lon عمود وبالعكس ، لذلك واضح الإصلاح أن تسمية تلك الأعمدة.لذا كان خدعة:

create table points_tmp as select id, lon as lat, lat as lon from points;
drop table points;
alter table points_tmp rename to points;

آمل أن يكون هذا سيكون من المفيد بالنسبة لك!

نقلا عن سكليتي الوثائق:

سكليتي يدعم مجموعة فرعية محدودة من ALTER TABLE.الأمر ALTER TABLE في SQLite يسمح للمستخدم إعادة تسمية الجدول أو لإضافة عمود جديد إلى الجدول الموجود. فإنه ليس من الممكن إعادة تسمية كولوم, إزالة عمود ، أو إضافة أو إزالة القيود من الجدول.

ما يمكنك القيام به بالطبع هو إنشاء جدول جديد مع التصميم الجديد ، SELECT * FROM old_table, و ملء الجدول الجديد مع القيم سوف تتلقى.

أولا، هذا هو واحد من تلك الأشياء التي تفرض في وجهي باستغراب: إعادة تسمية عمود يتطلب تهيئة جدول جديد تماما ونسخ البيانات من الجدول القديم إلى الجدول الجديد ...

واجهة المستخدم الرسومية لقد هبطت إلى القيام بعمليات سكليتي هو href="http://menial.co.uk/base/" قاعدة . انها حصلت على نافذة دخول أنيق يظهر كافة الأوامر التي تم تنفيذها. تفعل إعادة تسمية عمود عبر قاعدة بملء نافذة سجل مع الأوامر اللازمة:

وهذه يمكن بعد ذلك نسخ ولصق بسهولة حيث قد يحتاجون إليها. بالنسبة لي، هذا إلى ActiveAndroid ملف الهجرة. لمسة لطيفة، أيضا، هو أن البيانات التي تم نسخها يشمل فقط الأوامر سكليتي، وليس الطوابع، الخ.

ونأمل أن يوفر بعض الناس وقت.

العمود تغيير الجدول إلى <_ID>

 String LastId = "id";

    database.execSQL("ALTER TABLE " + PhraseContract.TABLE_NAME + " RENAME TO " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("CREATE TABLE " + PhraseContract.TABLE_NAME
    +"("
            + PhraseContract.COLUMN_ID + " INTEGER PRIMARY KEY,"
            + PhraseContract.COLUMN_PHRASE + " text ,"
            + PhraseContract.COLUMN_ORDER  + " text ,"
            + PhraseContract.COLUMN_FROM_A_LANG + " text"
    +")"
    );
    database.execSQL("INSERT INTO " +
            PhraseContract.TABLE_NAME + "("+ PhraseContract.COLUMN_ID +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +")" +
            " SELECT " + LastId +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +
            " FROM " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("DROP TABLE " + PhraseContract.TABLE_NAME + "old");

وكما ذكر من قبل، هناك متصفح قاعدة البيانات أداة سكليتي الذي يفعل ذلك. Lyckily، هذه الأداة يحتفظ بسجل لجميع العمليات التي يقوم بها المستخدم أو التطبيق. القيام بذلك مرة واحدة ويبحث في سجل التطبيق، سترى رمز المعنية. نسخ ولصق الاستعلام كما هو مطلوب. عملت بالنسبة لي. ويساعد هذا الأمل

وإنشاء عمود جديد مع اسم العمود المطلوب: COLNew.

ALTER TABLE {tableName} ADD COLUMN COLNew {type};

نسخ محتويات COLOld العمود القديم إلى عمود جديد COLNew.

INSERT INTO {tableName} (COLNew) SELECT {COLOld} FROM {tableName}

ملحوظة: ضرورية في السطر أعلاه بين قوسين.

من الوثائق الرسمية

أبسط وأسرع الإجراءات يمكن اختياريا أن تستخدم بعض التغييرات التي لا تؤثر على القرص المحتوى في أي شكل من الأشكال.التالية أبسط الإجراء المناسب لإزالة الاختيار أو الأجنبية الرئيسية أو NOT NULL القيود ، إعادة تسمية الأعمدة, أو إضافة أو إزالة أو تغيير القيم الافتراضية على عمود.

  1. بدء المعاملة.

  2. تشغيل PRAGMA schema_version لتحديد المخطط الحالي رقم الإصدار.هذا الرقم سوف تكون هناك حاجة إلى الخطوة 6 أدناه.

  3. تفعيل مخطط التحرير باستخدام PRAGMA writable_schema=على.

  4. تشغيل عبارة UPDATE على تغيير تعريف الجدول X في sqlite_master الجدول:تحديث sqlite_master مجموعة sql=...حيث type='table' و name='X';

    تنبيه:مما يجعل تغيير على sqlite_master الجدول مثل هذا سوف يجعل قاعدة البيانات تالفة وغير قابلة للقراءة إذا كان التغيير يحتوي على خطأ في بناء جملة.ويقترح أن اختبار دقيق التحديث بيان على فصل قاعدة بيانات فارغة قبل استخدامه على قاعدة بيانات تحتوي على بيانات هامة.

  5. إذا كان التغيير إلى الجدول X يؤثر أيضا على غيرها من جداول أو فهارس أو مشغلات الآراء داخل المخطط ، ثم قم بتشغيل تحديث البيانات تعديل تلك الجداول والفهارس وجهات النظر أيضا.على سبيل المثال إذا كان اسم العمود التغييرات كل قيود المفاتيح الخارجية, مشغلات, فهارس, و وجهات النظر التي تشير إلى هذا العمود يجب تعديلها.

    تنبيه:مرة أخرى إجراء تغييرات على sqlite_master الجدول مثل هذا سوف يجعل قاعدة البيانات تالفة وغير قابلة للقراءة إذا كان التغيير يحتوي على خطأ.بعناية اختبار هذا الإجراء بأكمله على اختبار منفصلة قاعدة البيانات قبل استخدامه على قاعدة بيانات تحتوي على بيانات هامة و/أو عمل نسخ احتياطية من قواعد بيانات هامة قبل تشغيل هذا الإجراء.

  6. الزيادة المخطط رقم الإصدار باستخدام PRAGMA schema_version=X حيث X هي واحدة من أكثر القديمة المخطط رقم الإصدار الموجود في الخطوة 2 أعلاه.

  7. تعطيل مخطط التحرير باستخدام PRAGMA writable_schema=قبالة.

  8. (اختياري) تشغيل PRAGMA integrity_check للتحقق من أن التغييرات المخطط لم تلف قاعدة البيانات.

  9. ارتكاب الصفقة بدأت في الخطوة 1 أعلاه.

وخيار واحد، إذا كنت في حاجة إليها القيام به في السؤال، وإذا تم إنشاء العمود الأول مع الافتراضي، هو خلق العمود الجديد الذي تريد نسخ محتويات أكثر من ذلك، وأساسا "التخلي عن" العمود القديم (يبقى الحالي، لكنك فقط لا تستخدم / تحديثه، الخ.)

مثال:

alter table TABLE_NAME ADD COLUMN new_column_name TYPE NOT NULL DEFAULT '';
update TABLE_NAME set new_column_name = old_column_name;
update TABLE_NAME set old_column_name = ''; -- abandon old column, basically

وهذا يترك خلف عمود (وإذا تم إنشاؤه مع NOT NULL ولكن من دون تقصير، وتدرج بعد ذلك في المستقبل أن تجاهل ذلك قد تفشل)، ولكن لو كان مجرد طاولة بخس، قد يكون المفاضلات مقبول. على خلاف ذلك استخدام واحدة من الإجابات الأخرى المذكورة هنا، أو قاعدة بيانات مختلفة تسمح الأعمدة ويجب إعادة تسميته.

حالة 1 :سكليتي 3.25.0+

فقط نسخة 3.25.0 سكليتي يدعم تسمية الأعمدة.إذا كان الجهاز الخاص بك هو تلبية هذا المطلب ، أشياء بسيطة للغاية.أدناه الاستعلام حل مشكلتك:

ALTER TABLE "MyTable" RENAME COLUMN "OldColumn" TO "NewColumn";

الحالة 2 :سكليتي الإصدارات القديمة

عليك أن تتبع طريقة مختلفة للحصول على النتيجة التي قد تكون صعبة قليلا

على سبيل المثال, إذا كان لديك مثل هذا الجدول:

CREATE TABLE student(Name TEXT, Department TEXT, Location TEXT)

و إذا كنت ترغب في تغيير اسم العمود Location

الخطوة 1: إعادة تسمية الجدول الأصلي:

ALTER TABLE student RENAME TO student_temp;

الخطوة 2: الآن إنشاء جدول جديد student مع تصحيح اسم العمود:

CREATE TABLE student(Name TEXT, Department TEXT, Address TEXT)

الخطوة 3: نسخ البيانات من الجدول الأصلي إلى جدول جديد:

INSERT INTO student(Name, Department, Address) SELECT Name, Department, Location FROM student_temp;

ملاحظة:الأمر أعلاه يجب أن يكون كل واحد خط.

الخطوة 4: إسقاط الجدول الأصلي:

DROP TABLE student_temp;

مع هذه الخطوات الأربع يمكنك يدويا تغيير أي سكليتي الجدول.نضع في اعتبارنا أن كنت سوف تحتاج أيضا إلى إعادة أي مؤشرات المشاهدين أو المشغلات على الجدول الجديد أيضا.

ومنذ إصدار 2018/09/15 (3.25.0) الدعم سكليتي إعادة تسمية الأعمدة

https://sqlite.org/changes.html

وsqlite3 yourdb .dump> /tmp/db.txt
تحرير /tmp/db.txt تغيير اسم العمود في خلق خط
sqlite2 yourdb2 ام / نقل yourdb2 yourdb

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top