আপনি যদি একবারে একটি লাইন প্রয়োগ করেন তবে এই সমস্ত উত্তর ঠিক আছে। তবে, আসল প্রশ্নটি ছিল এমন একটি স্কিল স্ক্রিপ্ট ইনপুট করা যা একক ডিবি এক্সিকিউট দ্বারা চালিত হবে এবং সমস্ত সমাধান (যেমন কলামটি আগে সময় আছে কিনা তা পরীক্ষা করে দেখার জন্য) এক্সিকিউটিভ প্রোগ্রামের প্রয়োজন হয় কোন টেবিলগুলির জ্ঞান থাকতে হবে এবং কলামগুলি পরিবর্তন / যুক্ত করা হচ্ছে বা এই তথ্য নির্ধারণের জন্য ইনপুট স্ক্রিপ্টের প্রাক-প্রসেসিং এবং পার্সিং করা হচ্ছে। সাধারণত আপনি রিয়েলটাইম বা প্রায়শই এটি চালাবেন না। সুতরাং একটি ব্যতিক্রম ধরা ধারণাটি গ্রহণযোগ্য এবং তারপরে এগিয়ে চলেছে। এর মধ্যে সমস্যা রয়েছে ... কীভাবে এগিয়ে যেতে হবে। ভাগ্যক্রমে ত্রুটি বার্তা আমাদের এটি করার জন্য প্রয়োজনীয় সমস্ত তথ্য দেয়। ধারণাটিটি হয় যে এসকিএলটি কার্যকর করতে যদি এটি কোনও পরিবর্তিত টেবিল কল ব্যাতিক্রম করে আমরা এসকিউএল-তে পরিবর্তিত টেবিল লাইনটি খুঁজে পেতে পারি এবং বাকী রেখাগুলি ফিরিয়ে আনতে পারি এবং এটি সফল না হওয়া অবধি কার্যকর করা হয় না বা পরিবর্তিত টেবিল লাইন খুঁজে পাওয়া যায় না। এখানে কিছু উদাহরণ কোড রয়েছে যেখানে আমাদের কাছে অ্যারেতে স্ক্রিপ্ট স্ক্রিপ্ট রয়েছে। আমরা প্রতিটি স্ক্রিপ্ট এক্সিকিউটিং অ্যারে পুনরাবৃত্তি। অলটার টেবিল কমান্ড ব্যর্থ হওয়ার জন্য আমরা এটি দু'বার কল করি তবে প্রোগ্রামটি সফল হয় কারণ আমরা এসকিএল থেকে অল্টার টেবিল কমান্ডটি সরিয়ে দিয়ে আপডেট কোডটি আবার প্রয়োগ করি।
exec /opt/usr8.6.3/bin/tclsh8.6 "$0" ${1+"$@"}
foreach pkg {sqlite3 } {
if { [ catch {package require {*}$pkg } err ] != 0 } {
puts stderr "Unable to find package $pkg\n$err\n ... adjust your auto_path!";
}
}
array set sqlArray {
1 {
CREATE TABLE IF NOT EXISTS Notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name text,
note text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
);
CREATE TABLE IF NOT EXISTS Version (
id INTEGER PRIMARY KEY AUTOINCREMENT,
version text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
);
INSERT INTO Version(version) values('1.0');
}
2 {
CREATE TABLE IF NOT EXISTS Tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name text,
tag text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
);
ALTER TABLE Notes ADD COLUMN dump text;
INSERT INTO Version(version) values('2.0');
}
3 {
ALTER TABLE Version ADD COLUMN sql text;
INSERT INTO Version(version) values('3.0');
}
}
sqlite3 db :memory:
proc createSchema { sqlArray } {
upvar $sqlArray sql
foreach version [lsort -integer [array names sql ] ] {
set cmd $sql($version)
set ok 0
while { !$ok && [string length $cmd ] } {
try {
db eval $cmd
set ok 1 ;
} on error { err backtrace } {
if { [regexp {duplicate column name: ([a-zA-Z0-9])} [string trim $err ] match columnname ] } {
puts "Error: $err ... trying again"
set cmd [removeAlterTable $cmd $columnname ]
} else {
throw DBERROR "$err\n$backtrace"
}
}
}
}
}
proc removeAlterTable { sqltext columnname } {
set mode skip
set result [list]
foreach line [split $sqltext \n ] {
if { [string first "alter table" [string tolower [string trim $line] ] ] >= 0 } {
if { [string first $columnname $line ] } {
set mode add
continue;
}
}
if { $mode eq "add" } {
lappend result $line
}
}
if { $mode eq "skip" } {
puts stderr "Unable to find matching alter table line"
return ""
} elseif { [llength $result ] } {
return [ join $result \n ]
} else {
return ""
}
}
proc printSchema { } {
db eval { select * from sqlite_master } x {
puts "Table: $x(tbl_name)"
puts "$x(sql)"
puts "
}
}
createSchema sqlArray
printSchema
createSchema sqlArray
printSchema
প্রত্যাশিত আউটপুট
Table: Notes
CREATE TABLE Notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name text,
note text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
, dump text)
Table: sqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)
Table: Version
CREATE TABLE Version (
id INTEGER PRIMARY KEY AUTOINCREMENT,
version text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
, sql text)
Table: Tags
CREATE TABLE Tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name text,
tag text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
)
Error: duplicate column name: dump ... trying again
Error: duplicate column name: sql ... trying again
Table: Notes
CREATE TABLE Notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name text,
note text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
, dump text)
Table: sqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)
Table: Version
CREATE TABLE Version (
id INTEGER PRIMARY KEY AUTOINCREMENT,
version text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
, sql text)
Table: Tags
CREATE TABLE Tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name text,
tag text,
createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
)
user_version
? আমি শূন্য অনুমান করি, তবে সেই নথিটি দেখতে ভাল লাগবে be