【发布时间】:2010-03-26 03:07:36
【问题描述】:
我想知道是否有一个很好的 IF NOT EXISTS 用于检查 SQLite 中的列和索引,还是我需要带回整个数据库架构并对此进行验证?
【问题讨论】:
我想知道是否有一个很好的 IF NOT EXISTS 用于检查 SQLite 中的列和索引,还是我需要带回整个数据库架构并对此进行验证?
【问题讨论】:
有一个名为sqlite_master 的系统目录表,您可以使用它来检查索引(或其他)名称:
SELECT name FROM sqlite_master WHERE type='index' ORDER BY name;
您可以使用pragma 来获取索引列:
PRAGMA index_info(index-name);
这个是用来获取表的列名的:
PRAGMA table_info(table-name);
【讨论】:
是的,sqlite 支持以下语法:CREATE INDEX IF NOT EXISTS ...
要检查列是否存在,您可以简单地尝试执行类似SELECT col from TABLE 的操作。如果它没有返回错误,则您的表包含 col。
【讨论】:
在 SQLite 中,如果你想检查你的列/字段是否存在于你的表中......试试这个答案对我有用...... https://stackoverflow.com/a/28146506/3126569
Cursor res = db.rawQuery("PRAGMA table_info("+tableName+")",null);
int value = res.getColumnIndex(fieldName);
【讨论】:
我就是这么干的,
INSERT INTO AUDITEVENT (CODE, DESCRIPTION, AUDITEVENTPK)
SELECT 'value1', 'value2', 'value3'
WHERE NOT EXISTS (SELECT 1 FROM AUDITEVENT WHERE CODE = 'value1')
在我的 IDConneciton 中,我有一个名为 ProcessCommandText 的方法,用于将查询从 SQL Server 语法更新为仅 SQLite。
这是那个方法的实现
public string ProcessSqlText(string text)
{
var result = text.Replace("SET ANSI_NULLS ON", "").
Replace("SET ANSI_NULLS ON", "").
Replace(" ASC)", ")").
Replace("TOP 100", "TOP(100)").
Replace("TOP 1", "TOP(1)").
Replace(" VARCHAR", " NVARCHAR").
Replace(" CHAR", " NCHAR").
Replace(" TEXT", " NTEXT").
Replace("WITH ( IGNORE_DUP_KEY = OFF)", "").
Replace("SET QUOTED_IDENTIFIER ON", "").
Replace("SET ANSI_PADDING ON", "").
Replace("SET ANSI_PADDING OFF", "").
Replace("SET ANSI_WARNINGS ON", "").Trim(' ').
Replace("WITH NOCHECK", "").
Replace("(nolock)", "").
Replace("CREATE CLUSTERED INDEX", "CREATE NONCLUSTERED INDEX").
Replace("CREATE UNIQUE CLUSTERED INDEX", "CREATE UNIQUE NONCLUSTERED INDEX").
Replace("[dbo].", "").
ToUpper().
Replace("NEWID()", "'" + Guid.NewGuid().ToString() + "'"). // NEWID() is not supported
Replace("GO", ""); // GO is not supported
if (result.Contains("TOP(100)"))
{
result = result.Replace("TOP(100)", "");
result += " LIMIT 100";
}
if (result.Contains("TOP(1)"))
{
result = result.Replace("TOP(1)", "");
result += " LIMIT 1";
}
if (result.Contains("DATEPART"))
{
result = result.Replace("DATEPART", "strftime");
result = result.Replace("minute", "'%M'");
result = result.Replace("day", "'%d'");
result = result.Replace("month", "'%m'");
result = result.Replace("year", "'%Y'");
}
result = TransformIfNotExistsQueriesToSqlLite(result);
return result;
}
private string TransformIfNotExistsQueriesToSqlLite(string query)
{
var ifNotExistsRegEx = @"(IF NOT EXISTS\s+)\(+.+\)+\r+\n+INSERT+";
var m = Regex.Match(query, @"(IF NOT EXISTS\s+)\(+.+\)+\r+\n+INSERT+", RegexOptions.IgnoreCase);
if (m.Groups.Count > 0 && m.Groups[0].Value.Contains("IF NOT EXISTS"))
{
var conditionalStatement = m.Groups[0].Value;
var newQuery = query.Replace(conditionalStatement, " INSERT ");
conditionalStatement = conditionalStatement.ToUpper().Replace("IF", "WHERE").Replace("INSERT", "");
newQuery = Regex.Replace(newQuery.ToUpper(), @"VALUES\s+\(+", " SELECT ");
var lastIndexOfClosingBracket = newQuery.LastIndexOf(')');
newQuery = newQuery.Substring(0, lastIndexOfClosingBracket);
return newQuery + " " + conditionalStatement;
}
return query;
}
【讨论】:
为什么不直接捕获异常?例如:
try{
db.execSQL("ALTER TABLE ACCOUNT_ENTRY ADD COLUMN ID_CONCEPT NUMBER(10)");
}catch(Exception e){
System.out.println(e);
}
【讨论】:
Exception 绝不是一个好主意。这只是为您的代码设置问题,并使您或将来需要在您调试后维护此代码的开发人员更难。