如何在SQLite中可靠地检查特定用户表是否存在?
我不是在询问像检查“select *”语句是否返回错误之类的不可靠方法(这是一个好主意吗?)。
原因如下:
在我的程序中,如果某些表不存在,我需要创建并填充它们。
如果这些表已经存在,我需要更新一些表。
是否应该采取其他方式来表示所涉及的表已经被创建 - 比如,在我的程序初始化/设置文件中创建/放置/设置某个标志或者类似操作?
还是我的方法有道理?
如何在SQLite中可靠地检查特定用户表是否存在?
我不是在询问像检查“select *”语句是否返回错误之类的不可靠方法(这是一个好主意吗?)。
原因如下:
在我的程序中,如果某些表不存在,我需要创建并填充它们。
如果这些表已经存在,我需要更新一些表。
是否应该采取其他方式来表示所涉及的表已经被创建 - 比如,在我的程序初始化/设置文件中创建/放置/设置某个标志或者类似操作?
还是我的方法有道理?
SELECT "name" FROM pragma_table_info("table_name") LIMIT 1;
sqlite_master
检查更好(对我来说),因为它还将检查附加和临时数据库。如果你正在处理大数据表,我使用 Python 和 Sqlite 制作了一个简单的技巧,你可以用任何其他语言实现相似的想法。
步骤1:在创建表时不要使用(if not exists)命令。
如果你已经在之前创建过该表并且想再次创建它,运行此命令将会抛出异常,因此需要执行第二步。
步骤2:使用 try 和 except(或其他语言的 try 和 catch)来处理最后一个异常。
如果你之前没有创建过该表,try 代码块将继续执行,但如果你已经创建过该表,你可以在 except 代码块中进行相关操作,从而知道你已经创建了该表。
以下是代码:
def create_table():
con = sqlite3.connect("lists.db")
cur = con.cursor()
try:
cur.execute('''CREATE TABLE UNSELECTED(
ID INTEGER PRIMARY KEY)''')
print('the table is created Now')
except sqlite3.OperationalError:
print('you already created the table before')
con.commit()
cur.close()
您还可以使用数据库元数据来检查表是否存在。
DatabaseMetaData md = connection.getMetaData();
ResultSet resultSet = md.getTables(null, null, tableName, null);
if (resultSet.next()) {
return true;
}
resultSet
。 - birgersp在Swift中,数据库中是否存在表
func tableExists(_ tableName:String) -> Bool {
sqlStatement = "SELECT name FROM sqlite_master WHERE type='table' AND name='\(tableName)'"
if sqlite3_prepare_v2(database, sqlStatement,-1, &compiledStatement, nil) == SQLITE_OK {
if sqlite3_step(compiledStatement) == SQLITE_ROW {
return true
}
else {
return false
}
}
else {
return false
}
sqlite3_finalize(compiledStatement)
}
如果您正在使用Python文件并且显然使用sqlite3,请打开命令提示符或bash,无论您使用什么都可以使用
我想在Diego Vélez的回答中补充关于PRAGMA
语句的内容。
从https://sqlite.org/pragma.html获取一些有用的函数,可以返回有关我们数据库的信息。 这里我引用了以下内容:
For example, information about the columns in an index can be read using the index_info pragma as follows:
PRAGMA index_info('idx52');
Or, the same content can be read using:
SELECT * FROM pragma_index_info('idx52');
The advantage of the table-valued function format is that the query can return just a subset of the PRAGMA columns, can include a WHERE clause, can use aggregate functions, and the table-valued function can be just one of several data sources in a join...
迭戈的回答提供了PRAGMA table_info(table_name)
这样的选项,但这在其他查询中并没有太大用处。
因此,为了回答OP的问题并改进迭戈的答案,您可以执行以下操作
SELECT * FROM pragma_table_info('table_name');
或者更好的是,
SELECT name FROM pragma_table_list('table_name');
如果你想模仿PoorLuzers最受欢迎的答案。
这是我用于SQLite Cordova的代码:
get_columnNames('LastUpdate', function (data) {
if (data.length > 0) { // In data you also have columnNames
console.log("Table full");
}
else {
console.log("Table empty");
}
});
还有另一个:
function get_columnNames(tableName, callback) {
myDb.transaction(function (transaction) {
var query_exec = "SELECT name, sql FROM sqlite_master WHERE type='table' AND name ='" + tableName + "'";
transaction.executeSql(query_exec, [], function (tx, results) {
var columnNames = [];
var len = results.rows.length;
if (len>0){
var columnParts = results.rows.item(0).sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').split(','); ///// RegEx
for (i in columnParts) {
if (typeof columnParts[i] === 'string')
columnNames.push(columnParts[i].split(" ")[0]);
};
callback(columnNames);
}
else callback(columnNames);
});
});
}
这个 C++ 函数检查数据库和所有附加的数据库是否存在表格(可选列)。
bool exists(sqlite3 *db, string tbl, string col="1")
{
sqlite3_stmt *stmt;
bool b = sqlite3_prepare_v2(db, ("select "+col+" from "+tbl).c_str(),
-1, &stmt, 0) == SQLITE_OK;
sqlite3_finalize(stmt);
return b;
}
编辑:最近发现了sqlite3_table_column_metadata函数。因此
bool exists(sqlite3* db,const char *tbl,const char *col=0)
{return sqlite3_table_column_metadata(db,0,tbl,col,0,0,0,0,0)==SQLITE_OK;}
public class LoginService : ILoginService
{
private SQLiteConnection dbconn;
}
public int ExisteSesion()
{
var rs = dbconn.GetTableInfo("Sesion");
return rs.Count;
}
如果表不存在,它只会返回0;如果表存在,则表示它具有数据,并返回它拥有的总行数。
在模型中,我已经指定了表必须接收的名称,以确保其正确运行。
[Table("Sesion")]
public class Sesion
{
[PrimaryKey]
public int Id { get; set; }
public string Token { get; set; }
public string Usuario { get; set; }
}
SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}';
ATTACH DATABASE AS schema-name
然后在附加的模式中找不到表
要知道除了'main'之外的模式中是否存在表,您需要遍历所有模式,例如schema-name.sqlite_master。
为了解决这个问题,我看到有两个选择:
第二个选项可以通过使用以下方法来完成:
select * from pragma_database_list
SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type="table" AND name="table_name");
似乎将结果缩减为布尔值结果(只能是0或1,没有其他值) - undefined