将 Cursor 直接插入 table in Android
Insert a Cursor directly into a table in Android
我有一个 sqlite.SQLiteCursor
实例和一个 Table
实例,它们具有相同的架构(相同的列)。我想将游标中的数据插入 table。我可以从游标中提取数据并使用 SQLiteDatabase#insert()
方法,但是有没有一种方法可以在内部执行它们?例如,如果我有多个 tables 和相关游标,为每一对创建多个用于插入的方法是一项耗时的任务。
is there a method that does them internally?
我不这么认为,因为 Cursor 不一定是单个 table 的全部内容,而且 Cursor 通常可以有派生列(例如 column_x + column y AS new_column
)和其他连接的列tables.
如果传递 table 名称和 Cursor 来提取列名 (Cursor#getColumnNames()
) 并构建 INSERT SQL 对于任何 cursor/table 组合 IF 游标和 Table 列名匹配(更难但可能忽略不在 table 中的列可能利用 the table_info PRAGMA).
表示不一定需要中间 Cursor,因为您可以使用 INSERT INTO newtable SELECT * FROM old_table;
工作示例(原始)
DBhelper.java
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TBL_MASTER = "master";
public static final String COL_ID = BaseColumns._ID;
public static final String COL_NAME = "name";
public static final String COL_OTHER = "other";
public static final String COL_MYBLOB = "myblob";
public static final String COL_MYFLOAT = "myfloat";
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crt_table_sql = "CREATE TABLE IF NOT EXISTS " + TBL_MASTER + "(" +
COL_ID + " INTEGER PRIMARY KEY," +
COL_NAME + " TEXT," +
COL_OTHER + " TEXT," +
COL_MYBLOB + " BLOB," +
COL_MYFLOAT + " REAL " +
")";
db.execSQL(crt_table_sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public long insertData(String name, String other, byte[] myblob,float myfloat ) {
ContentValues cv = new ContentValues();
cv.put(COL_NAME,name);
cv.put(COL_OTHER,other);
cv.put(COL_MYBLOB,myblob);
cv.put(COL_MYFLOAT,myfloat);
return mDB.insert(TBL_MASTER,null,cv);
}
public Cursor getAll() {
return getFromTable(TBL_MASTER);
}
public Cursor getFromTable(String table_name) {
return mDB.query(table_name,null,null,null,null,null,null);
}
public boolean createTableBasedUponAnotherTable(String existing_table_name, String new_table_name) {
boolean rv = false;
String sql_column = "sql";
String whereclause = "name=? AND type = ?";
String[] whereargs = new String[]{existing_table_name,"table"};
String[] columns = new String[]{sql_column};
Cursor csr = mDB.query("sqlite_master",columns,whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
String sql = csr.getString(csr.getColumnIndex(sql_column)).replace(existing_table_name,new_table_name).replace("CREATE TABLE","CREATE TABLE IF NOT EXISTS");
mDB.execSQL(sql);
rv = true;
}
csr.close();
return rv;
}
private boolean ifTableExists(String table_name) {
boolean rv = false;
String whereclause = "name=? AND type = ?";
String[] whereargs = new String[]{table_name,"table"};
Cursor csr = mDB.query("sqlite_master",null,null,null,null,null,null);
if (csr.moveToFirst()) {
rv = true;
}
csr.close();
return rv;
}
public boolean copyTableViaCursor(Cursor csr, String table_name) {
boolean rv = false;
mDB.beginTransaction();
ContentValues cv = new ContentValues();
int rows_processed;
if(!ifTableExists(table_name)) {
csr.moveToPosition(-1); // just in case position the cursor to before the first row
while (csr.moveToNext()) {
cv.clear();
for (int i=0; i < csr.getColumnCount(); i++) {
switch (csr.getType(i)) {
case Cursor.FIELD_TYPE_BLOB:
cv.put(csr.getColumnName(i),csr.getBlob(i));
break;
case Cursor.FIELD_TYPE_FLOAT:
cv.put(csr.getColumnName(i),csr.getFloat(i));
break;
case Cursor.FIELD_TYPE_INTEGER:
cv.put(csr.getColumnName(i),csr.getInt(i));
break;
case Cursor.FIELD_TYPE_STRING:
cv.put(csr.getColumnName(i),csr.getString(i));
break;
}
}
mDB.insert(table_name,null,cv);
}
mDB.setTransactionSuccessful();
}
mDB.endTransaction();
return rv;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
DBHelper mDBHlpr;
Cursor csr;
String new_table = DBHelper.TBL_MASTER + "_new";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHlpr = new DBHelper(this);
mDBHlpr.insertData("Fred","more about fred",new byte[]{7,8,4,55,67,127,126,99},321.76894F);
mDBHlpr.insertData("Bert","something or other about bert",new byte[]{1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0},1234567890.675342F);
mDBHlpr.insertData("Mary","definitely not something about Mary",new byte[]{},0.000000000000F);
DatabaseUtils.dumpCursor(csr = mDBHlpr.getAll());
mDBHlpr.createTableBasedUponAnotherTable(DBHelper.TBL_MASTER,new_table);
mDBHlpr.copyTableViaCursor(csr,new_table);
csr = mDBHlpr.getFromTable(new_table);
DatabaseUtils.dumpCursor(csr);
csr.close();
}
}
日志输出:-
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@268ba35
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: 0 {
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=1
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Fred
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: other=more about fred
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=321.769
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: 1 {
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=2
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Bert
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: other=something or other about bert
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=1.23457e+09
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: 2 {
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=3
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Mary
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: other=definitely not something about Mary
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=0
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: <<<<<
2019-01-05 19:03:56.795 4211-4211/ptfc.populatetablefromcursor I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@268ba35
2019-01-05 19:03:56.795 4211-4211/ptfc.populatetablefromcursor I/System.out: 0 {
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=1
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Fred
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: other=more about fred
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=321.769
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: 1 {
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=2
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Bert
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: other=something or other about bert
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=1.23457e+09
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: 2 {
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=3
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Mary
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: other=definitely not something about Mary
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=0
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: <<<<<
我有一个 sqlite.SQLiteCursor
实例和一个 Table
实例,它们具有相同的架构(相同的列)。我想将游标中的数据插入 table。我可以从游标中提取数据并使用 SQLiteDatabase#insert()
方法,但是有没有一种方法可以在内部执行它们?例如,如果我有多个 tables 和相关游标,为每一对创建多个用于插入的方法是一项耗时的任务。
is there a method that does them internally?
我不这么认为,因为 Cursor 不一定是单个 table 的全部内容,而且 Cursor 通常可以有派生列(例如 column_x + column y AS new_column
)和其他连接的列tables.
如果传递 table 名称和 Cursor 来提取列名 (Cursor#getColumnNames()
) 并构建 INSERT SQL 对于任何 cursor/table 组合 IF 游标和 Table 列名匹配(更难但可能忽略不在 table 中的列可能利用 the table_info PRAGMA).
表示不一定需要中间 Cursor,因为您可以使用 INSERT INTO newtable SELECT * FROM old_table;
工作示例(原始)
DBhelper.java
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TBL_MASTER = "master";
public static final String COL_ID = BaseColumns._ID;
public static final String COL_NAME = "name";
public static final String COL_OTHER = "other";
public static final String COL_MYBLOB = "myblob";
public static final String COL_MYFLOAT = "myfloat";
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crt_table_sql = "CREATE TABLE IF NOT EXISTS " + TBL_MASTER + "(" +
COL_ID + " INTEGER PRIMARY KEY," +
COL_NAME + " TEXT," +
COL_OTHER + " TEXT," +
COL_MYBLOB + " BLOB," +
COL_MYFLOAT + " REAL " +
")";
db.execSQL(crt_table_sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public long insertData(String name, String other, byte[] myblob,float myfloat ) {
ContentValues cv = new ContentValues();
cv.put(COL_NAME,name);
cv.put(COL_OTHER,other);
cv.put(COL_MYBLOB,myblob);
cv.put(COL_MYFLOAT,myfloat);
return mDB.insert(TBL_MASTER,null,cv);
}
public Cursor getAll() {
return getFromTable(TBL_MASTER);
}
public Cursor getFromTable(String table_name) {
return mDB.query(table_name,null,null,null,null,null,null);
}
public boolean createTableBasedUponAnotherTable(String existing_table_name, String new_table_name) {
boolean rv = false;
String sql_column = "sql";
String whereclause = "name=? AND type = ?";
String[] whereargs = new String[]{existing_table_name,"table"};
String[] columns = new String[]{sql_column};
Cursor csr = mDB.query("sqlite_master",columns,whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
String sql = csr.getString(csr.getColumnIndex(sql_column)).replace(existing_table_name,new_table_name).replace("CREATE TABLE","CREATE TABLE IF NOT EXISTS");
mDB.execSQL(sql);
rv = true;
}
csr.close();
return rv;
}
private boolean ifTableExists(String table_name) {
boolean rv = false;
String whereclause = "name=? AND type = ?";
String[] whereargs = new String[]{table_name,"table"};
Cursor csr = mDB.query("sqlite_master",null,null,null,null,null,null);
if (csr.moveToFirst()) {
rv = true;
}
csr.close();
return rv;
}
public boolean copyTableViaCursor(Cursor csr, String table_name) {
boolean rv = false;
mDB.beginTransaction();
ContentValues cv = new ContentValues();
int rows_processed;
if(!ifTableExists(table_name)) {
csr.moveToPosition(-1); // just in case position the cursor to before the first row
while (csr.moveToNext()) {
cv.clear();
for (int i=0; i < csr.getColumnCount(); i++) {
switch (csr.getType(i)) {
case Cursor.FIELD_TYPE_BLOB:
cv.put(csr.getColumnName(i),csr.getBlob(i));
break;
case Cursor.FIELD_TYPE_FLOAT:
cv.put(csr.getColumnName(i),csr.getFloat(i));
break;
case Cursor.FIELD_TYPE_INTEGER:
cv.put(csr.getColumnName(i),csr.getInt(i));
break;
case Cursor.FIELD_TYPE_STRING:
cv.put(csr.getColumnName(i),csr.getString(i));
break;
}
}
mDB.insert(table_name,null,cv);
}
mDB.setTransactionSuccessful();
}
mDB.endTransaction();
return rv;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
DBHelper mDBHlpr;
Cursor csr;
String new_table = DBHelper.TBL_MASTER + "_new";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHlpr = new DBHelper(this);
mDBHlpr.insertData("Fred","more about fred",new byte[]{7,8,4,55,67,127,126,99},321.76894F);
mDBHlpr.insertData("Bert","something or other about bert",new byte[]{1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0},1234567890.675342F);
mDBHlpr.insertData("Mary","definitely not something about Mary",new byte[]{},0.000000000000F);
DatabaseUtils.dumpCursor(csr = mDBHlpr.getAll());
mDBHlpr.createTableBasedUponAnotherTable(DBHelper.TBL_MASTER,new_table);
mDBHlpr.copyTableViaCursor(csr,new_table);
csr = mDBHlpr.getFromTable(new_table);
DatabaseUtils.dumpCursor(csr);
csr.close();
}
}
日志输出:-
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@268ba35
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: 0 {
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=1
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Fred
2019-01-05 19:03:56.791 4211-4211/ptfc.populatetablefromcursor I/System.out: other=more about fred
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=321.769
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: 1 {
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=2
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Bert
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: other=something or other about bert
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.792 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=1.23457e+09
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: 2 {
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=3
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Mary
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: other=definitely not something about Mary
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=0
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.793 4211-4211/ptfc.populatetablefromcursor I/System.out: <<<<<
2019-01-05 19:03:56.795 4211-4211/ptfc.populatetablefromcursor I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@268ba35
2019-01-05 19:03:56.795 4211-4211/ptfc.populatetablefromcursor I/System.out: 0 {
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=1
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Fred
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: other=more about fred
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=321.769
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: 1 {
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=2
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Bert
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: other=something or other about bert
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=1.23457e+09
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: 2 {
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: _id=3
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: name=Mary
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: other=definitely not something about Mary
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myblob=<unprintable>
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: myfloat=0
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: }
2019-01-05 19:03:56.796 4211-4211/ptfc.populatetablefromcursor I/System.out: <<<<<