2011-03-19 4 views
6

이 예외에 대한 다른 질문을 본 적이 있지만 모두 기본 키가 지정된 행이 이미 존재하는 솔루션으로 해결되는 것으로 보입니다. 이것은 나를위한 것 같지 않습니다. 내 문자열의 모든 작은 따옴표를 큰 따옴표로 바꾸려고 시도했지만 동일한 문제가 발생합니다. 내가 수행하여 만든 SQLite 데이터베이스의 설정 테이블에 행을 삽입하기 위해 노력하고있어안드로이드 SQLiteConstraintException : 오류 코드 19 : 제약 조건이 실패했습니다

다음

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

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 문자열은 다음과 같이 정의된다 내가 삽입을 실행할 때

는하지만, 난 항상 얻을 :

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 

그것은 참조 ms 인 것처럼 내 삽입에있는 모든 열이 null이 아닙니다. 행의 기본 키는 테이블의 유일한 행이기 때문에 고유해야합니다. 따라서 내가 생각할 수있는 유일한 것은 내 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

+0

시도해도 여전히 작동하지 않았습니다. 당신이 옳은 것은 내가 뭘 검사하는지 각 요소 주위에 쉼표로 구분 된 아포스트로피가 있다는 것입니다. 그게 옳지 않은가? –

+0

아래에 게시 한 답변을 볼 수 있다면 기본적으로 옳았습니다. –

답변

0

작은 따옴표를 이스케이프 처리해 보셨습니까? 예 :

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

그래도 고쳐지지 않으면, 단 하나의 열만 있어도 문제가 해결 될 것입니다. 한 번에 하나씩 각 열을 추가하여 문제의 원인이되는 열을 파악할 수 있습니다.

+0

제안 해 주셔서 감사합니다. 작은 따옴표를 이스케이프해도 문제가 해결되지 않으므로 내가 제안한대로 할 수 있습니다. –

+0

나는 당신이 제안한대로했고 매우 간단한 테이블을 만들었습니다. Insert 환경 설정에 insert 환경 설정을 추가하자마자 insert가 실패하기 시작합니다. 따라서 CHECK 조건이 잘못되어 있어야합니다. –

1

안드로이드 put (string, string) 메서드는 이미 값 문자열 주위에 따옴표를 추가 한 것 같습니다 ... 수동으로 따옴표를 사용하자 마자 (예 : "허용"문자열에서) CHECK에 전달하는 문자열은 문제가 해결되었습니다.

+0

예. 'ContentValues'는 리터럴로 바인딩됩니다. CREATE TABLE과 같은 원시 SQL에서는 문자열 리터럴에 따옴표를 사용해야합니다. – laalto

관련 문제