উত্তর:
থেকে: http://www.sqlite.org/faq.html :
(১১) আমি কীভাবে এসকিউএলাইটে বিদ্যমান সারণী থেকে কলামগুলি যুক্ত করব বা মুছব।
এসকিউএলাইটে অল্টার টেবল সমর্থন সীমিত রয়েছে যা আপনি কোনও টেবিলের শেষে একটি কলাম যুক্ত করতে বা কোনও টেবিলের নাম পরিবর্তন করতে পারেন। আপনি যদি কোনও টেবিলের কাঠামোর আরও জটিল পরিবর্তন করতে চান তবে আপনাকে টেবিলটি পুনরায় তৈরি করতে হবে। আপনি অস্থায়ী টেবিলটিতে বিদ্যমান ডেটা সংরক্ষণ করতে পারেন, পুরানো টেবিলটি ফেলে দিতে পারেন, নতুন টেবিলটি তৈরি করতে পারেন, তারপরে অস্থায়ী সারণী থেকে ডেটাটি অনুলিপি করতে পারেন।
উদাহরণস্বরূপ, ধরুন আপনার কাছে "t1" নামের একটি সারণী রয়েছে যার সাথে কলামের নাম "এ", "বি" এবং "সি" রয়েছে এবং আপনি এই টেবিল থেকে "গ" কলামটি মুছতে চান। নিম্নলিখিত পদক্ষেপগুলি কীভাবে এটি করা যেতে পারে তা চিত্রিত করে:
BEGIN TRANSACTION; CREATE TEMPORARY TABLE t1_backup(a,b); INSERT INTO t1_backup SELECT a,b FROM t1; DROP TABLE t1; CREATE TABLE t1(a,b); INSERT INTO t1 SELECT a,b FROM t1_backup; DROP TABLE t1_backup; COMMIT;
TEMPORARY
থেকে CREATE TABLE
।
ব্যাকআপ টেবিলটি বাদ দেওয়ার পরিবর্তে কেবল এটির পুনরায় নামকরণ করুন ...
BEGIN TRANSACTION;
CREATE TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
ALTER TABLE t1_backup RENAME TO t1;
COMMIT;
t1
।
সরলতার জন্য, কেন নির্বাচনী বিবৃতি থেকে ব্যাকআপ টেবিল তৈরি করবেন না?
CREATE TABLE t1_backup AS SELECT a, b FROM t1;
DROP TABLE t1;
ALTER TABLE t1_backup RENAME TO t1;
TEXT
।
এই বিকল্পটি কেবল তখনই কাজ করে যদি আপনি এসকিউএলাইটের জন্য ডিবি ব্রাউজারের মতো ডিবি ব্রাউজারে ডিবি খুলতে পারেন ।
এসকিউলাইটের জন্য ডিবি ব্রাউজারে:
=> নিম্নলিখিত প্রশ্নের সাথে সরাসরি একটি নতুন টেবিল তৈরি করুন:
CREATE TABLE table_name (Column_1 TEXT,Column_2 TEXT);
=> এখন নিম্নলিখিত প্রশ্নের সাথে টেবিল_নামে বিদ্যমান_ টেবিল থেকে ডেটাটি প্রবেশ করান:
INSERT INTO table_name (Column_1,Column_2) FROM existing_table;
=> এখন নিম্নলিখিত ক্যোয়ারী দ্বারা বিদ্যমান_তালিকাটি ফেলে দিন:
DROP TABLE existing_table;
এসকিউএলাইট 3 সি ++ এর জন্য:
void GetTableColNames( tstring sTableName , std::vector<tstring> *pvsCols )
{
UASSERT(pvsCols);
CppSQLite3Table table1;
tstring sDML = StringOps::std_sprintf(_T("SELECT * FROM %s") , sTableName.c_str() );
table1 = getTable( StringOps::tstringToUTF8string(sDML).c_str() );
for ( int nCol = 0 ; nCol < table1.numFields() ; nCol++ )
{
const char* pch1 = table1.fieldName(nCol);
pvsCols->push_back( StringOps::UTF8charTo_tstring(pch1));
}
}
bool ColExists( tstring sColName )
{
bool bColExists = true;
try
{
tstring sQuery = StringOps::std_sprintf(_T("SELECT %s FROM MyOriginalTable LIMIT 1;") , sColName.c_str() );
ShowVerbalMessages(false);
CppSQLite3Query q = execQuery( StringOps::tstringTo_stdString(sQuery).c_str() );
ShowVerbalMessages(true);
}
catch (CppSQLite3Exception& e)
{
bColExists = false;
}
return bColExists;
}
void DeleteColumns( std::vector<tstring> *pvsColsToDelete )
{
UASSERT(pvsColsToDelete);
execDML( StringOps::tstringTo_stdString(_T("begin transaction;")).c_str() );
std::vector<tstring> vsCols;
GetTableColNames( _T("MyOriginalTable") , &vsCols );
CreateFields( _T("TempTable1") , false );
tstring sFieldNamesSeperatedByCommas;
for ( int nCol = 0 ; nCol < vsCols.size() ; nCol++ )
{
tstring sColNameCurr = vsCols.at(nCol);
bool bUseCol = true;
for ( int nColsToDelete = 0; nColsToDelete < pvsColsToDelete->size() ; nColsToDelete++ )
{
if ( pvsColsToDelete->at(nColsToDelete) == sColNameCurr )
{
bUseCol = false;
break;
}
}
if ( bUseCol )
sFieldNamesSeperatedByCommas+= (sColNameCurr + _T(","));
}
if ( sFieldNamesSeperatedByCommas.at( int(sFieldNamesSeperatedByCommas.size()) - 1) == _T(','))
sFieldNamesSeperatedByCommas.erase( int(sFieldNamesSeperatedByCommas.size()) - 1 );
tstring sDML;
sDML = StringOps::std_sprintf(_T("insert into TempTable1 SELECT %s FROM MyOriginalTable;\n") , sFieldNamesSeperatedByCommas.c_str() );
execDML( StringOps::tstringTo_stdString(sDML).c_str() );
sDML = StringOps::std_sprintf(_T("ALTER TABLE MyOriginalTable RENAME TO MyOriginalTable_old\n") );
execDML( StringOps::tstringTo_stdString(sDML).c_str() );
sDML = StringOps::std_sprintf(_T("ALTER TABLE TempTable1 RENAME TO MyOriginalTable\n") );
execDML( StringOps::tstringTo_stdString(sDML).c_str() );
sDML = ( _T("DROP TABLE MyOriginalTable_old;") );
execDML( StringOps::tstringTo_stdString(sDML).c_str() );
execDML( StringOps::tstringTo_stdString(_T("commit transaction;")).c_str() );
}
আমি একটি পাইথন ফাংশন করেছি যেখানে আপনি আর্গুমেন্ট হিসাবে সরানোর জন্য টেবিল এবং কলামে প্রবেশ করেছেন:
def removeColumn(table, column):
columns = []
for row in c.execute('PRAGMA table_info(' + table + ')'):
columns.append(row[1])
columns.remove(column)
columns = str(columns)
columns = columns.replace("[", "(")
columns = columns.replace("]", ")")
for i in ["\'", "(", ")"]:
columns = columns.replace(i, "")
c.execute('CREATE TABLE temptable AS SELECT ' + columns + ' FROM ' + table)
c.execute('DROP TABLE ' + table)
c.execute('ALTER TABLE temptable RENAME TO ' + table)
conn.commit()
ডুডা এবং মেবিগাফ্যাটগুয়ের উত্তরগুলির তথ্য অনুসারে টেবিলে কোনও বিদেশী কী থাকলে এটি কাজ করবে না, তবে এটি 2 লাইন কোডের সাথে সংশোধন করা যেতে পারে (একটি নতুন টেবিল তৈরি করে কেবল অস্থায়ী টেবিলটির নামকরণ নয়)
যদি কারও কাছে (প্রায়) ব্যবহারের জন্য প্রস্তুত পিএইচপি ফাংশন প্রয়োজন হয় তবে নিম্নলিখিত এই উত্তরের উপর ভিত্তি করে :
/**
* Remove a column from a table.
*
* @param string $tableName The table to remove the column from.
* @param string $columnName The column to remove from the table.
*/
public function DropTableColumn($tableName, $columnName)
{
// --
// Determine all columns except the one to remove.
$columnNames = array();
$statement = $pdo->prepare("PRAGMA table_info($tableName);");
$statement->execute(array());
$rows = $statement->fetchAll(PDO::FETCH_OBJ);
$hasColumn = false;
foreach ($rows as $row)
{
if(strtolower($row->name) !== strtolower($columnName))
{
array_push($columnNames, $row->name);
}
else
{
$hasColumn = true;
}
}
// Column does not exist in table, no need to do anything.
if ( !$hasColumn ) return;
// --
// Actually execute the SQL.
$columns = implode('`,`', $columnNames);
$statement = $pdo->exec(
"CREATE TABLE `t1_backup` AS SELECT `$columns` FROM `$tableName`;
DROP TABLE `$tableName`;
ALTER TABLE `t1_backup` RENAME TO `$tableName`;");
}
অন্যান্য উত্তরের বিপরীতে, এই পদ্ধতিতে ব্যবহৃত এসকিউএল কলামগুলির উপাত্তের প্রকারগুলি সংরক্ষণ করে বলে মনে হচ্ছে, অন্যদিকে স্বীকৃত উত্তরের মতো এমন কিছু ফল রয়েছে যা সমস্ত কলামের মতো হয়ে গেছে TEXT
।
আপডেট 1:
ব্যবহৃত এসকিউএল এর এমন অপূর্ণতা রয়েছে যা autoincrement
কলামগুলি সংরক্ষণ করা যায় না ।
কেবল যদি এটি আমার মতো কাউকে সহায়তা করতে পারে।
অফিসিয়াল ওয়েবসাইট এবং স্বীকৃত উত্তরের উপর ভিত্তি করে আমি সি # ব্যবহার করে একটি কোড তৈরি করেছি যা System.Data.SQLite নুগেট প্যাকেজ ব্যবহার করে ।
এই কোডটি প্রাথমিক কী এবং বিদেশী কী সংরক্ষণ করে ।
সি # তে কোড:
void RemoveColumnFromSqlite (string tableName, string columnToRemove) {
try {
var mSqliteDbConnection = new SQLiteConnection ("Data Source=db_folder\\MySqliteBasedApp.db;Version=3;Page Size=1024;");
mSqliteDbConnection.Open ();
// Reads all columns definitions from table
List<string> columnDefinition = new List<string> ();
var mSql = $"SELECT type, sql FROM sqlite_master WHERE tbl_name='{tableName}'";
var mSqliteCommand = new SQLiteCommand (mSql, mSqliteDbConnection);
string sqlScript = "";
using (mSqliteReader = mSqliteCommand.ExecuteReader ()) {
while (mSqliteReader.Read ()) {
sqlScript = mSqliteReader["sql"].ToString ();
break;
}
}
if (!string.IsNullOrEmpty (sqlScript)) {
// Gets string within first '(' and last ')' characters
int firstIndex = sqlScript.IndexOf ("(");
int lastIndex = sqlScript.LastIndexOf (")");
if (firstIndex >= 0 && lastIndex <= sqlScript.Length - 1) {
sqlScript = sqlScript.Substring (firstIndex, lastIndex - firstIndex + 1);
}
string[] scriptParts = sqlScript.Split (new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in scriptParts) {
if (!s.Contains (columnToRemove)) {
columnDefinition.Add (s);
}
}
}
string columnDefinitionString = string.Join (",", columnDefinition);
// Reads all columns from table
List<string> columns = new List<string> ();
mSql = $"PRAGMA table_info({tableName})";
mSqliteCommand = new SQLiteCommand (mSql, mSqliteDbConnection);
using (mSqliteReader = mSqliteCommand.ExecuteReader ()) {
while (mSqliteReader.Read ()) columns.Add (mSqliteReader["name"].ToString ());
}
columns.Remove (columnToRemove);
string columnString = string.Join (",", columns);
mSql = "PRAGMA foreign_keys=OFF";
mSqliteCommand = new SQLiteCommand (mSql, mSqliteDbConnection);
int n = mSqliteCommand.ExecuteNonQuery ();
// Removes a column from the table
using (SQLiteTransaction tr = mSqliteDbConnection.BeginTransaction ()) {
using (SQLiteCommand cmd = mSqliteDbConnection.CreateCommand ()) {
cmd.Transaction = tr;
string query = $"CREATE TEMPORARY TABLE {tableName}_backup {columnDefinitionString}";
cmd.CommandText = query;
cmd.ExecuteNonQuery ();
cmd.CommandText = $"INSERT INTO {tableName}_backup SELECT {columnString} FROM {tableName}";
cmd.ExecuteNonQuery ();
cmd.CommandText = $"DROP TABLE {tableName}";
cmd.ExecuteNonQuery ();
cmd.CommandText = $"CREATE TABLE {tableName} {columnDefinitionString}";
cmd.ExecuteNonQuery ();
cmd.CommandText = $"INSERT INTO {tableName} SELECT {columnString} FROM {tableName}_backup;";
cmd.ExecuteNonQuery ();
cmd.CommandText = $"DROP TABLE {tableName}_backup";
cmd.ExecuteNonQuery ();
}
tr.Commit ();
}
mSql = "PRAGMA foreign_keys=ON";
mSqliteCommand = new SQLiteCommand (mSql, mSqliteDbConnection);
n = mSqliteCommand.ExecuteNonQuery ();
} catch (Exception ex) {
HandleExceptions (ex);
}
}
PRAGMA foreign_keys=off;
BEGIN TRANSACTION;
ALTER TABLE table1 RENAME TO _table1_old;
CREATE TABLE table1 (
( column1 datatype [ NULL | NOT NULL ],
column2 datatype [ NULL | NOT NULL ],
...
);
INSERT INTO table1 (column1, column2, ... column_n)
SELECT column1, column2, ... column_n
FROM _table1_old;
COMMIT;
PRAGMA foreign_keys=on;
আরও তথ্যের জন্য: https://www.techonthenet.com/sqlite/tables/alter_table.php