2011-03-19 13 views
6

He visto otras preguntas sobre esta excepción, pero todas parecen resolverse con la solución de que ya existe una fila con la clave principal especificada. Este no parece ser el caso para mí. He intentado reemplazar todas las comillas simples en mis cadenas con comillas dobles, pero ocurre el mismo problema.Android SQLiteConstraintException: código de error 19: restricción fallida

Estoy intentando insertar una fila en la tabla de configuración de la base de datos SQLite que he creado de la siguiente manera:

db.execSQL("DROP TABLE IF EXISTS "+Settings.SETTINGS_TABLE_NAME + ";"); 
db.execSQL(CREATE_MEDIA_TABLE); 
db.execSQL(CREATE_SETTINGS_TABLE); 
Cursor c = getAllSettings(); 
//If there isn't already a settings row, create a row full of defaults 
if(c.getCount()==0){ 
    ContentValues cv = new ContentValues(); 
    cv.put(Settings.SETTING_UNIQUE_ID, "'"+Settings.uniqueID+"'");   
    cv.put(Settings.SETTING_DEVICE_ID, Settings.SETTING_DEVICE_ID_DEFAULT); 
    cv.put(Settings.SETTING_CONNECTION_PREFERENCE, Settings.SETTING_CONNECTION_PREFERENCE_DEFAULT); 
    cv.put(Settings.SETTING_AD_HOC_ENABLED, Settings.SETTING_AD_HOC_ENABLED_DEFAULT); 
    cv.put(Settings.SETTING_SERVER_ADDRESS, Settings.SETTING_SERVER_ADDRESS_DEFAULT); 
    cv.put(Settings.SETTING_RECORDING_MODE, Settings.SETTING_RECORDING_MODE_DEFAULT); 
    cv.put(Settings.SETTING_PREVIEW_ENABLED, Settings.SETTING_PREVIEW_ENABLED_DEFAULT); 
    cv.put(Settings.SETTING_PICTURE_RESOLUTION_X, Settings.SETTING_PICTURE_RESOLUTION_X_DEFAULT); 
    cv.put(Settings.SETTING_PICTURE_RESOLUTION_Y, Settings.SETTING_PICTURE_RESOLUTION_Y_DEFAULT); 
    cv.put(Settings.SETTING_VIDEO_RESOLUTION_X, Settings.SETTING_VIDEO_RESOLUTION_X_DEFAULT); 
    cv.put(Settings.SETTING_VIDEO_RESOLUTION_Y, Settings.SETTING_VIDEO_RESOLUTION_Y_DEFAULT); 
    cv.put(Settings.SETTING_VIDEO_FPS, Settings.SETTING_VIDEO_FPS_DEFAULT); 
    cv.put(Settings.SETTING_AUDIO_BITRATE_KBPS, Settings.SETTING_AUDIO_BITRATE_KBPS_DEFAULT); 
    cv.put(Settings.SETTING_STORE_TO_SD, Settings.SETTING_STORE_TO_SD_DEFAULT); 
    cv.put(Settings.SETTING_STORAGE_LIMIT_MB, Settings.SETTING_STORAGE_LIMIT_MB_DEFAULT); 

    this.db.insert(Settings.SETTINGS_TABLE_NAME, null, cv); 
} 

La cadena CREATE_SETTINGS_TABLE se define como la siguiente:

private static String CREATE_SETTINGS_TABLE = "CREATE TABLE IF NOT EXISTS " + Settings.SETTINGS_TABLE_NAME + "(" 
+ Settings.SETTING_UNIQUE_ID + " TEXT NOT NULL PRIMARY KEY, " 
+ Settings.SETTING_DEVICE_ID + " TEXT NOT NULL , " 
+ Settings.SETTING_CONNECTION_PREFERENCE + " TEXT NOT NULL CHECK("+Settings.SETTING_CONNECTION_PREFERENCE+" IN("+Settings.SETTING_CONNECTION_PREFERENCE_ALLOWED+")), " 
+ Settings.SETTING_AD_HOC_ENABLED + " TEXT NOT NULL CHECK("+Settings.SETTING_AD_HOC_ENABLED+" IN("+Settings.SETTING_AD_HOC_ENABLED_ALLOWED+")), " 
+ Settings.SETTING_SERVER_ADDRESS + " TEXT NOT NULL, " 
+ Settings.SETTING_RECORDING_MODE + " TEXT NOT NULL CHECK("+Settings.SETTING_RECORDING_MODE+" IN("+Settings.SETTING_RECORDING_MODE_ALLOWED+")), " 
+ Settings.SETTING_PREVIEW_ENABLED + " TEXT NOT NULL CHECK("+Settings.SETTING_PREVIEW_ENABLED+" IN("+Settings.SETTING_PREVIEW_ENABLED_ALLOWED+")), " 
+ Settings.SETTING_PICTURE_RESOLUTION_X + " TEXT NOT NULL, " 
+ Settings.SETTING_PICTURE_RESOLUTION_Y + " TEXT NOT NULL, " 
+ Settings.SETTING_VIDEO_RESOLUTION_X + " TEXT NOT NULL, " 
+ Settings.SETTING_VIDEO_RESOLUTION_Y + " TEXT NOT NULL, " 
+ Settings.SETTING_VIDEO_FPS + " TEXT NOT NULL, " 
+ Settings.SETTING_AUDIO_BITRATE_KBPS + " TEXT NOT NULL, " 
+ Settings.SETTING_STORE_TO_SD + " TEXT NOT NULL CHECK("+Settings.SETTING_STORE_TO_SD+" IN("+Settings.SETTING_STORE_TO_SD_ALLOWED+")), " 
+ Settings.SETTING_STORAGE_LIMIT_MB + " TEXT NOT NULL)"; 

Sin embargo, cuando ejecuto mi inserción, siempre me sale:

03-19 19:37:36.974: ERROR/Database(386): Error inserting server_address='0.0.0.0' storage_limit='-1' connection='none' preview_enabled='0' sd_enabled='1' video_fps='15' audio_bitrate='96' device_id='-1' recording_mode='none' picture_resolution_x='-1' picture_resolution_y='-1' unique_id='000000000000000' adhoc_enable='0' video_resolution_x='320' video_resolution_y='240' 
03-19 19:45:34.284: ERROR/Database(446): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed 

vER ms como si todas las columnas en mi inserción no fueran nulas. La clave principal de la fila TIENE que ser única, porque es la única fila en la tabla. Por lo tanto, lo único que puedo pensar es que mis condiciones de CHEQUE no son ciertas. Aquí están las cadenas predefinidas que estoy usando:

public static final String SETTING_UNIQUE_ID = "unique_id"; 

public static final String SETTING_DEVICE_ID = "device_id"; 
public static final String SETTING_DEVICE_ID_DEFAULT = "'-1'"; 

public static final String SETTING_CONNECTION_PREFERENCE = "connection"; 
public static final String SETTING_CONNECTION_PREFERENCE_3G = "'3g'"; 
public static final String SETTING_CONNECTION_PREFERENCE_WIFI = "'wifi'"; 
public static final String SETTING_CONNECTION_PREFERENCE_NONE = "'none'"; 
public static final String SETTING_CONNECTION_PREFERENCE_ALLOWED = SETTING_CONNECTION_PREFERENCE_3G+","+SETTING_CONNECTION_PREFERENCE_WIFI+","+SETTING_CONNECTION_PREFERENCE_NONE; 
public static final String SETTING_CONNECTION_PREFERENCE_DEFAULT = SETTING_CONNECTION_PREFERENCE_NONE; 

public static final String SETTING_AD_HOC_ENABLED = "adhoc_enable"; 
public static final String SETTING_AD_HOC_ENABLED_ALLOWED = TRUE+","+FALSE; 
public static final String SETTING_AD_HOC_ENABLED_DEFAULT = FALSE; 

public static final String SETTING_SERVER_ADDRESS = "server_address"; 
public static final String SETTING_SERVER_ADDRESS_DEFAULT = "'0.0.0.0'"; 

public static final String SETTING_RECORDING_MODE = "recording_mode"; 
public static final String SETTING_RECORDING_MODE_VIDEO = "'video'"; 
public static final String SETTING_RECORDING_MODE_AUDIO = "'audio'"; 
public static final String SETTING_RECORDING_MODE_PICTURE = "'picture'"; 
public static final String SETTING_RECORDING_MODE_NONE = "'none'"; 
public static final String SETTING_RECORDING_MODE_ALLOWED = SETTING_RECORDING_MODE_VIDEO+","+SETTING_RECORDING_MODE_AUDIO+","+SETTING_RECORDING_MODE_PICTURE+","+SETTING_RECORDING_MODE_NONE; 
public static final String SETTING_RECORDING_MODE_DEFAULT = SETTING_RECORDING_MODE_NONE; 

public static final String SETTING_PREVIEW_ENABLED = "preview_enabled"; 
public static final String SETTING_PREVIEW_ENABLED_ALLOWED = TRUE+","+FALSE; 
public static final String SETTING_PREVIEW_ENABLED_DEFAULT = FALSE; 

public static final String SETTING_PICTURE_RESOLUTION_X = "picture_resolution_x"; 
public static final String SETTING_PICTURE_RESOLUTION_X_DEFAULT = "'-1'"; 

public static final String SETTING_PICTURE_RESOLUTION_Y = "picture_resolution_y"; 
public static final String SETTING_PICTURE_RESOLUTION_Y_DEFAULT = "'-1'"; 

public static final String SETTING_VIDEO_RESOLUTION_X = "video_resolution_x"; 
public static final String SETTING_VIDEO_RESOLUTION_X_DEFAULT = "'320'"; 

public static final String SETTING_VIDEO_RESOLUTION_Y = "video_resolution_y"; 
public static final String SETTING_VIDEO_RESOLUTION_Y_DEFAULT = "'240'"; 

public static final String SETTING_VIDEO_FPS = "video_fps"; 
public static final String SETTING_VIDEO_FPS_DEFAULT = "'15'"; 

public static final String SETTING_AUDIO_BITRATE_KBPS = "audio_bitrate"; 
public static final String SETTING_AUDIO_BITRATE_KBPS_DEFAULT = "'96'"; 

public static final String SETTING_STORE_TO_SD = "sd_enabled"; 
public static final String SETTING_STORE_TO_SD_ALLOWED = TRUE+","+FALSE; 
public static final String SETTING_STORE_TO_SD_DEFAULT = TRUE; 

public static final String SETTING_STORAGE_LIMIT_MB = "storage_limit"; 
public static final String SETTING_STORAGE_LIMIT_MB_DEFAULT = "'-1'"; 

public static final String SETTING_CLIP_LENGTH_SECONDS = "clip_length"; 
public static final String SETTING_CLIP_LENGTH_SECONDS_DEFAULT = "'300'"; 

¿Alguien ve lo que podría estar pasando? Estoy perplejo. Gracias por adelantado.

+0

¿Has probado con 'connection =" 'none' "' Puedo imaginar que tienes esos CHECK con el apóstrofo – Pentium10

+0

Lo intenté, todavía no funcionó. Tiene razón en que lo que estoy revisando tiene apóstrofes alrededor de cada elemento, separados por comas. ¿No es eso correcto? –

+0

Si ves la respuesta que publiqué a continuación, básicamente tenías razón. –

Respuesta

0

¿Has probado a escapar tus comillas simples? p.ej.

public static final String SETTING_SERVER_ADDRESS_DEFAULT = "\'0.0.0.0\'"; 

Si eso no soluciona el problema, me gustaría romper todo abajo hasta que sólo tiene una sola columna, y conseguir que funcione. A continuación, agregue cada columna de a una por vez para que pueda averiguar cuál es la que está causando el problema.

+0

Gracias por la sugerencia. Escapar las comillas simples no soluciona el problema, así que puedo hacer lo que sugiera. –

+0

Hice lo que sugirió, y creé una tabla muy simple. La inserción comienza a fallar tan pronto como agrego la preferencia de conexión a la instrucción create la inserción, por lo que algo debe estar mal con mi condición CHECK. –

1

Parece que el método android put (string, string) ya debe agregar comillas alrededor de su cadena de valor ... tan pronto como tomé las cotizaciones manuales que había estado ingresando alrededor de mis cadenas de valor (pero las guardé en las cadenas "PERMITIDAS" que estaba pasando a CHECK, el problema fue resuelto.

+0

Sí. 'ContentValues' se enlazará como literales, mientras que en SQL sin formato, como su' CREATE TABLE', tendrá que usar comillas para literales de cadenas. – laalto

Cuestiones relacionadas