2011-03-19 85 views
6

我已經看到關於此異常的其他問題,但它們似乎都解決了使用指定主鍵的行已存在的解決方案。這似乎並不適合我。我試圖用雙引號替換我的字符串中的所有單引號,但同樣的問題發生。Android SQLiteConstraintException:錯誤代碼19:約束失敗

我試圖插入一行到我做創建的SQLite數據庫的設置表如下:

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); 
} 

的CREATE_SETTINGS_TABLE字符串定義如下:

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)"; 

然而,當我執行我的插入,我總是得到:

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 

它看毫秒,就好像我插入的所有列都不爲空。該行的主鍵必須是唯一的,因爲它是表中唯一的行。因此,我唯一能想到的是我的CHECK條件不正確。以下是我正在使用的預定義字符串:

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'"; 

有人看到會發生什麼嗎?我很難過。提前致謝。

+0

你用'connection =「'none'嘗試過嗎?''我可以想象你有那些帶撇號的檢查 – Pentium10 2011-03-19 20:36:55

+0

試過了,依然沒有奏效。你是正確的,我正在檢查的每個元素周圍有撇號,以逗號分隔。這是不對的? – 2011-03-19 23:50:05

+0

如果你看到我在下面發佈的答案,你基本上是對的。 – 2011-03-20 00:14:02

回答

0

您是否試過轉義單引號?例如

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

如果這樣不能解決它,我會把它全部分解,直到你只有一列,然後讓它工作。然後逐個添加一列,以便確定哪一個導致了問題。

+0

感謝您的建議。轉義單引號並不能解決問題,所以我可以按照你的建議去做。 – 2011-03-19 23:27:03

+0

我按照你的建議做了,並創建了一個非常簡單的表格。只要將連接首選項添加到插入的create語句,插入就開始失敗,因此,我的CHECK條件必須有錯誤。 – 2011-03-19 23:52:48

1

看來,Android的放(字符串,字符串)方法必須已經在你的值字符串周圍追加引號......只要我採取了手動引號,我一直在輸入我的值字符串(但讓他們在我傳給CHECK的「允許」字符串中,問題解決了。

+0

是的。 'ContentValues'將被綁定爲文字,而在原始SQL中,比如'CREATE TABLE',你將不得不使用引號來處理字符串。 – laalto 2013-12-18 22:10:37

相關問題