2011-04-03 47 views
1

我想顯示位置名稱根據城市名稱從數據庫中選擇,但它給錯誤沒有這樣的列古爾岡我保存我的sqlite管理器數據庫在資產文件夾.... 所以如何在SQLite和如何保存查詢結果中的android源碼可變運行嵌套查詢....感謝錯誤/ AndroidRuntime:導致:android.database.sqlite.SQLiteException:沒有這樣的列:Gurgaon:

package cabs.h; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import android.R.string; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.util.Log; 

public class DataBaseHelper extends SQLiteOpenHelper{ 
    //The Android's default system path of your application database. 
private static final int DATABASE_VERSION = 1; 
    private static String DB_PATH = "/data/data/cabs.h/databases/"; 
private static String DB_NAME = "CabBookingDatabase.sqlite"; 
private SQLiteDatabase myDataBase; 
private final Context myContext; 

/** 
* Constructor 
* Takes and keeps a reference of the passed context in order to access to the application assets and resources. 
* @param context 
*/ 
public DataBaseHelper(Context context) { 

    super(context, DB_NAME, null, DATABASE_VERSION); 
    this.myContext = context; 
} 

/** 
* Creates a empty database on the system and rewrites it with your own database. 
* */ 
public void createDataBase() throws IOException{ 

    boolean dbExist = checkDataBase(); 

    if (dbExist) { 
     Log.v("DB Exists", "db exists"); 
     // By calling this method here onUpgrade will be called on a 
     // writeable database, but only if the version number has been 
     // bumped 
     this.getWritableDatabase(); 
     } 
     dbExist = checkDataBase(); 
     if (!dbExist) { 
     // By calling this method and empty database will be created into 
     // the default system path of your application so we are gonna be 
     // able to overwrite that database with our database. 
     this.getReadableDatabase(); 

     try { 

     copyDataBase(); 

     } catch (IOException e) { 

      throw new Error("Error copying database"); 

     } 
    } 

} 

/** 
* Check if the database already exist to avoid re-copying the file each time you open the application. 
* @return true if it exists, false if it doesn't 
*/ 
private boolean checkDataBase(){ 

    SQLiteDatabase checkDB = null; 

    try{ 
     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

    }catch(SQLiteException e) 
    { 

     //database does't exist yet. 

    } 

    if(checkDB != null){ 

     checkDB.close(); 

    } 

    return checkDB != null ? true : false; 
} 

/** 
* Copies your database from your local assets-folder to the just created empty database in the 
* system folder, from where it can be accessed and handled. 
* This is done by transfering bytestream. 
* */ 
private void copyDataBase() throws IOException 
{ 

    //Open your local db as the input stream 
    InputStream myInput = myContext.getAssets().open(DB_NAME); 

    // Path to the just created empty db 
    String outFileName = DB_PATH + DB_NAME; 

    //Open the empty db as the output stream 
    OutputStream myOutput = new FileOutputStream(outFileName); 

    //transfer bytes from the inputfile to the outputfile 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = myInput.read(buffer))>0){ 
     myOutput.write(buffer, 0, length); 
    } 

    //Close the streams 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 

} 

public void openDataBase() throws SQLException{ 

    //Open the database 
    String myPath = DB_PATH + DB_NAME; 
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

} 

@Override 
public synchronized void close() { 

     if(myDataBase != null) 
      myDataBase.close(); 

     super.close(); 

} 

@Override 
public void onCreate(SQLiteDatabase db) { 

} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    Log.w("tag", "Upgrading database from version which will destroy all old data"); 
    db.execSQL("DROP TABLE IF EXISTS liberQuoti"); 
    onCreate(db); 

} 

public Cursor getcity() 
{ 
String myPath = DB_PATH + DB_NAME; 
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
Cursor cur ; 
cur = myDataBase.rawQuery("select cityName from CityType", null); 
int citynameIndex = cur.getColumnIndexOrThrow("cityName"); 
//String valuecity = cur.getString(citynameIndex); 
//Log.d("No.of tweets,,,,,,,", valuecity); 

cur.moveToFirst(); 
//Log.d("No.of tweets,,,,,,,", +accountnameIndex + "tgr"); 
myDataBase.close(); 


return cur; 
} 
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
public Cursor getloc() 
{ 
String myPath = DB_PATH + DB_NAME; 
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
Cursor cur1,cur2; 
String saa = cabbookingapplication.Selection; 
String sql="select CityType.rowid from CityType where CityType.cityName="+saa+""; 
// int sql=2; 
cur1 = myDataBase.rawQuery("select locationName from Location where cityId=("+sql+")", null); 
cur1.moveToFirst(); 
myDataBase.close(); 
return cur1; 
} 
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
public Cursor getservice() 
{ 
String myPath = DB_PATH + DB_NAME; 
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
Cursor cur3; 
cur3 = myDataBase.rawQuery("select serviceType from ServiceType", null); 
cur3.moveToFirst(); 
myDataBase.close(); 
return cur3; 
} 
public Cursor getcabtype() 
{ 
String myPath = DB_PATH + DB_NAME; 
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
Cursor cur4; 
cur4 = myDataBase.rawQuery("select carType from CarType", null); 
cur4.moveToFirst(); 
myDataBase.close(); 
return cur4; 
} 
public Cursor getcabservice() 
{ 
String myPath = DB_PATH + DB_NAME; 
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
Cursor cur5; 
cur5 = myDataBase.rawQuery("select cabFeatures from CabFeatures", null); 
cur5.moveToFirst(); 
myDataBase.close(); 
return cur5; 
} 
public Cursor getday() 
{ 
String myPath = DB_PATH + DB_NAME; 
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
Cursor cur6; 
cur6 = myDataBase.rawQuery("select dayTravell from DayTravell", null); 
cur6.moveToFirst(); 
myDataBase.close(); 
return cur6; 
} 

} 

回答

1
  1. 當您返回遊標時,您正在關閉數據庫 - 因此遊標將指向一個封閉的數據庫,這意味着您無法使用它(您可能能夠使用第一條記錄,因爲在關閉數據庫之前移至該數據庫) 。更不用說打開/關閉需要一些時間。您應該在onCreate中打開DB一次,然後在onDestroy中關閉一次。
  2. 的Android只支持rawQuery一個SQL語句,所以你要什麼都不能通過嵌套SQL語句

試着這麼做來實現:

String sql = "SELECT CityType.rowid, Location.locationName FROM Location, CityType " + 
    "WHERE Location.cityId = CityType.rowid " + 
    "AND CityType.cityName = " + saa; 

還請後從logcat的錯誤輸出。

您DatabaseHelper更改爲類似如下(請注意,我不是爲每個查詢打開數據庫 - 你需要請確保調用在活動的onCreateonDestroy方法openclose方法)。

public class DataBaseHelper extends SQLiteOpenHelper { 
    ... 

    private SQLiteDatabase mDb; 

    // change openDatabase to this: 
    // call it ONCE in onCreate of your activity 
    public SQLiteDatabase open() throws SQLException { 
     if (mDb != null) 
      return; // already opened 
     mDb = this.getReadableDatabase(); 
     return mDb; 
    } 
    // call this in the onDestroy of your activity 
    public void close() { 
     if (mDb == null) 
      return; // db is not open 
     mDb.close(); 
     mDb = null; 
    } 


    // Change getLoc and your other methods to be something like this 
    public Cursor getLocation() { 
     if (mDb == null) 
      throw new NullPointerException("Database has not been opened by activity"); 

     String saa = cabbookingapplication.Selection; 
     String sql = "SELECT CityType.rowid, Location.locationName FROM Location, CityType " + 
    "WHERE Location.cityId = CityType.rowid " + 
    "AND CityType.cityName = " + saa; 
     return mDb.rawQuery(sql); 
    } 
    ... 
} 

而且

  • 務必請你不要關閉幾乎馬上任何遊標以避免內存泄漏startManagingCursor(即您使用的適配器應加以管理遊標)
  • 我在我上面的例子中沒有調用Cursor.moveToFirst(),所以如果你想要的話調用。

我通常把它叫做我的適配器,所以我可以做這樣的事情

if (cursor.getCount() > 0) { 
    // we have at least 1 record 
    while (cursor.moveToNext()) { 
     // do something with current row 
    } 
} else { 
    // no rows, show an empty message or something 
} 
+0

@ joseph /data/data/cabs.h/databases/CabBookingDatabase.sqlite SQLiteDatabase創建並從未關閉 – SRam 2011-04-04 05:14:53

+0

伯爵嗨...它的作品,但問題是在「saa」變量的地方「null」是即將到來 – SRam 2011-04-04 07:38:53

+0

在我的帖子底部添加了代碼,以解釋使用適配器而不是每次都打開數據庫。 'saa'來自'cabbookingapplication.Selection'所以'Selection'必須爲空 - 我不必爲您的預訂應用程序的代碼,所以我不能說爲什麼這是null。 – 2011-04-04 19:14:20

0

嘗試使用IN代替=

String sql = "select CityType.rowid from CityType where CityType.cityName = " 
    + saa; 
cur1 = myDataBase.rawQuery(
    "SELECT locationName FROM Location WHERE cityId in (" + sql + ")", null); 

或者乾脆加入:

String sql = "SELECT locationName FROM Location, CityType " + 
    "where cityId = CityType.rowid " + 
    "AND CityType.cityName = " + saa; 

顯然,在某些設備上,你可能還需要關閉你打開數據庫與getReadableDatabase

SQLiteDatabase db = getReadableDatabase(); 
db.close(); 
+0

公共光標getloc()之外 { 字符串mypath中= DB_PATH + DB_NAME; myDataBase = SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READONLY); 光標cur1,cur2; 字符串saa = cabbookingapplication。選擇; String sql =「SELECT locationName FROM Location,CityType」+ 「where cityId = CityType.rowid」+ 「AND CityType.cityName =」+ saa; // int sql = 2; cur1 = myDataBase.rawQuery( \t \t sql,null); cur1.moveToFirst(); myDataBase.close(); return cur1; } – SRam 2011-04-03 07:56:29

+0

對我不適用locaion未顯示在微調框中並給出相同的錯誤 – SRam 2011-04-03 07:57:40

+0

您是否嘗試了最後一個建議? – 2011-04-03 08:00:55

相關問題