2013-08-16 3 views
1

ok ... 나는이 일에 상당히 매달렸다. sackoverflow에서 많이 검색했으나 문제를 해결할 수는 없었습니다. 문제는 : DB의 단일 열을 업데이트하려고하는데 항상 오류가 발생하고 작동하지 않으며 문제가 무엇인지 거의 알지 못합니다.안드로이드 DB 업데이트 레지스터

SQLiteDatabase.update()를 사용하려고했지만 작동하지 않고 execSQL (문자열)과 함께 사용하려고했습니다. 같은 오류.

누군가에게 어떤 문제가 있는지 아이디어가있는 경우 제 코드를 표시하고 제발 ... 제발 도와주세요. 그냥 작동하지 않습니다 ... 제발 아무것도

public void AbreouCriaBD(){ 
    try{ 
      String nomeBanco = "Usuarios"; 
      dataBase = openOrCreateDatabase(nomeBanco, MODE_WORLD_WRITEABLE, null); 
      String sql = "CREATE TABLE IF NOT EXISTS usuario" + 
      "(id INTEGER PRIMARY KEY, login TEXT, senha TEXT, saldoBanco float, saldoCredito float, saldoFuturos float)"; 
      dataBase.execSQL(sql); 


      }catch(Exception erro){ 
       Alerta("Erro BD","BD Não criado"); 
      } 


    } 

public void UpdateBDPrincipal(double saldo){ 

    String saldoString = String.valueOf(saldo); 
    try{dataBase.execSQL("UPDATE usuario SET 'saldoBanco'="+ saldoString +"WHERE 'login'= cristiano");} 
    catch(Exception error){ 
     Alerta("Erro","Erro no UPDATE"); 
    } 
} 



public void Alerta(String title,String message){ 
    AlertDialog.Builder Sucesso = new AlertDialog.Builder(TelaSaldoCredito.this); 
    Sucesso.setTitle(title); 
    Sucesso.setMessage(message); 
    Sucesso.setNeutralButton("ok", null); 
    Sucesso.show(); 

...

08-16 15:36:24.729: W/System.err(10855): java.lang.NullPointerException 
08-16 15:36:24.739: W/System.err(10855): at com.bunchoffat.financejournal.TelaSaldoCredito.UpdateBDPrincipal(TelaSaldoCredito.java:121) 
08-16 15:36:24.739: W/System.err(10855): at com.bunchoffat.financejournal.TelaSaldoCredito$1.onClick(TelaSaldoCredito.java:62) 
08-16 15:36:24.739: W/System.err(10855): at android.view.View.performClick(View.java:2579) 
08-16 15:36:24.739: W/System.err(10855): at android.view.View$PerformClick.run(View.java:9246) 
08-16 15:36:24.739: W/System.err(10855): at android.os.Handler.handleCallback(Handler.java:587) 
08-16 15:36:24.739: W/System.err(10855): at android.os.Handler.dispatchMessage(Handler.java:92) 
08-16 15:36:24.739: W/System.err(10855): at android.os.Looper.loop(Looper.java:130) 
08-16 15:36:24.739: W/System.err(10855): at android.app.ActivityThread.main(ActivityThread.java:3735) 
08-16 15:36:24.739: W/System.err(10855): at java.lang.reflect.Method.invokeNative(Native Method) 
08-16 15:36:24.739: W/System.err(10855): at java.lang.reflect.Method.invoke(Method.java:507) 
08-16 15:36:24.759: W/System.err(10855): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
08-16 15:36:24.759: W/System.err(10855): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:662) 
08-16 15:36:24.759: W/System.err(10855): at dalvik.system.NativeStart.main(Native Method) 

나는 오류가 NullPointerException이있다 볼 수 있습니다 ...하지만 ... 내가 왜 모르는있다. .. dataBase에 대한 데이터가 있습니다. 나는 그 시스템에 로그인 할 수 있고 데이터베이스에 암호가 있기 때문에 확신합니다. 그래서 .. 여기에 무엇을 놓치고 있습니까?

+0

이 db처럼 시도해보십시오.update (String table, ContentValues ​​values, String whereClause, String [] whereArgs) – Aravin

+0

이것 역시 시도해 보았지만 작동하지 않습니다. 이 사람은 까다 롭습니다. ContentValues에서 키 이름을 열 이름과 동일하게 설정해야합니다. 맞습니까? 그리고 whereClause에서 그냥 "login '= cristiano"맞습니까? 그것을 했어, 그리고 같은 오류 ... –

+0

우리는 또한 더 많은 정보가 필요할 수 있습니다. Android 공급자 패턴 (예 :'ContentProvider'에서 확장)을 사용합니까? 또한 SQLite를 추상화하여 업데이트 및 업그레이드를보다 쉽게 ​​해주는'SQLiteOpenHelper'를 사용하고 있습니까? – Tseng

답변

1

귀하의 검색어에 오류가 있습니다. saldoString을 추가 한 후에는 WHERE 문 앞에 공백이 없습니다.

public void UpdateBDPrincipal(double saldo){ 

    String saldoString = String.valueOf(saldo); 
    try{ 
     dataBase.execSQL("UPDATE usuario SET 'saldoBanco'="+ saldoString +" WHERE 'login'= cristiano"); 
    } catch(Exception error) { 
     Alerta("Erro","Erro no UPDATE"); 
    } 
} 

P.S. 이 방법으로 SQL 문자열을 작성할 때는 SQL 주입 공격에 취약 할 수 있으므로주의하십시오. Saldo가 double이기 때문에이 특별한 경우에는 "작동"합니다. 그러나 그것은 탈출 또는 ''

업데이트에 문자열을주지 않고 문자열을 작성하는 것은 매우 위험 문자열 될 경우 : 또한 예외 출력을 억제하지 마십시오,이 추적하게 오류가 훨씬 어렵습니다.

try { 
    } catch(Exception error) { 
     error.printStackTrace(); // Print error to the log 
     Alerta("Erro","Erro no UPDATE"); 
    } 

다음 logcat을 사용하여 Android 로그를 읽으십시오. 디버깅을 위해 Eclipse를 사용하는 경우 Logcat은 추가 된 창 중 하나입니다. 이클립스를 사용하거나 테스트하지 않는다면 명령 행에서 "adb logcat"을 실행하십시오 (스마트 폰은 USB를 통해 컴퓨터에 연결되어야합니다).

업데이트 2 : 여기 는 SQLiteOpenHelper를 사용하는 방법에 대한 예입니다.

public class MyServiceProvider extends ContentProvider { 
    private static final String TABLE_NAME = "usuario"; 
    private SQLiteDatabase db; 

    @Override 
    public boolean onCreate() { 
     // Initialize the database and assign it to the private variable 
     MyDatabaseHelper sqlHelper = new MyDatabaseHelper(getContext()); 
     db = sqlHelper.getReadableDatabase(); 

     return (db == null)?false:true; 
    } 

    public void UpdateBDPrincipal(double saldo){ 

     String saldoString = String.valueOf(saldo); 
     try { 
      dataBase.execSQL("UPDATE usuario SET 'saldoBanco'="+ saldoString +"WHERE 'login'= cristiano"); 
     } catch(Exception error) { 
      Alerta("Erro","Erro no UPDATE"); 
     } 
    } 
} 

class MyDatabaseHelper extends SQLiteOpenHelper { 
    private static final String LOG_TAG = "MyAppTag"; 
    private static final String DB_NAME = "Usuarios"; 
    private static final String TABLE_NAME = "usuario"; 
    private static final int DATABASE_VERSION = 2; 

    public MyDatabaseHelper(Context context){ 
     super(context, DB_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String sql = "CREATE TABLE IF NOT EXISTS usuario" + 
      "(id INTEGER PRIMARY KEY, login TEXT, senha TEXT, saldoBanco float, saldoCredito float, saldoFuturos float)"; 
     db.execSQL(sql); 
    } 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // Here you can perform updates when the database structure changes 
     // Begin transaction 
     db.beginTransaction(); 

     try { 
      if(oldVersion<2){ 
       // Upgrade database structure from Version 1 to 2 
       String alterTable = "ALTER ...."; 

       db.execSQL(alterTable); 
       Log.i(LOG_TAG,"Successfully upgraded to Version 2"); 
      } 

      db.setTransactionSuccessful(); 
     } catch(Exception ex){ 
      ex.printStackTrace(); 
     } finally { 
      // Ends transaction 
      // If there was an error, the database won't be altered 
      db.endTransaction(); 
     } 
    } 
} 

당신은 데이터베이스 생성 및로드 및 쿼리가 내장되거나 처리되는 방식 (즉, 업데이트를 대체하여, 쿼리 메소드를 삭제) 사이에 명확한 추상화가이 방법.

편집 : SQLiteDatabase.update() 사용법 :

private String userName = "cristiano"; 

ContentValues values = new ContentValues(); 
values.put("saldoBanco", 150.23); 

// define the WHERE clause but do not directly concat values into the string 
// Use question marks (?) as place holders. 
String whereClause = "WHERE login = ?"; 

// define a list of args. For each '?' used in WHERE clause, add one element to the array 
String[] whereArgs = new String[] { userName }; 

int numRowsUpdated = db.update(TABLE_NAME, values, whereClause, whereArgs); 

실행은 물음표 whereArgs의 요소로 대체됩니다. 첫 번째 물음표가 whereArgs의 첫 번째 요소로 대체됩니다, 두 번째 물음표는 쉽게 만들 곳 조항과 SQL 주입 취약점을 위험에 방지 할 수있는 두 번째 whereArgs

이 방법에 의해 대체 될 것이다.

+0

나는 공간을 어디에 넣었는지 ... 그리고 여전히 오류를 보여주고있다 ... 다른 건 없나요? –

+0

오류에 대해 더 자세히 알려 주실 수 있습니까? 당신의 오프닝 포스트에 logcat 출력을 추가하는 것과 같이? 코드를 올렸지 만 오류가 발생하지 않았 으면 어떤 원인인지 추측하기 어렵습니다. 오류 메시지는 그것이 발생하는 이유를 알아내는 것이 중요합니다. – Tseng

+0

또한 코드에서 실제 예외를 표시하지 않습니다. 에러 처리시 error.printStackTrace()를 추가해야 에러 메시지가 억제되는 대신 logcat 윈도우에 출력됩니다. – Tseng