恼人的数据库语法错误

时间:2017-11-05 14:24:36

标签: android sqlite android-sqlite android-contentprovider

我知道这个问题已被问过很多次,但我看不出我做错了什么。我有一个包含两个表的数据库。

public class MoviesDbHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
private static final int DATABASE_VERSION = 14;

public static final String DATABASE_NAME = "popular_movies.db";

public MoviesDbHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {

    final String SQL_CREATE_MOVIE__SETTING_TABLE = "CREATE TABLE " + MovieContract.MovieSettings.TABLE_NAME + " (" +
            MovieContract.MovieEntry._ID + " INTEGER PRIMARY KEY, " +
            MovieContract.MovieSettings.COL_MOVIE_SETTING + " TEXT UNIQUE NOT NULL " +
            " );";

    final String SQL_CREATE_MOVIE_TABLE = "CREATE TABLE " + MovieContract.MovieEntry.TABLE_NAME + " (" +
            MovieContract.MovieEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            MovieContract.MovieEntry.COL_MOVIE_KEY + " INTEGER NOT NULL, " +
            MovieContract.MovieEntry.COL_MOVIE_ID + " INTEGER NOT NULL, " +
            MovieContract.MovieEntry.COL_IS_ADULT + " TEXT NOT NULL, " +
            MovieContract.MovieEntry.COL_BACKDROP_PATH + " TEXT NOT NULL, " +
            MovieContract.MovieEntry.COL_ORIGINAL_LANGUAGE + " TEXT NOT NULL, " +
            MovieContract.MovieEntry.COL_ORIGINAL_TITLE + " TEXT NOT NULL," +
            MovieContract.MovieEntry.COL_OVERVIEW + " TEXT NOT NULL, " +
            MovieContract.MovieEntry.COL_TITLE + " TEXT NOT NULL, " +
            MovieContract.MovieEntry.COL_IS_VIDEO + " TEXT NOT NULL, " +
            MovieContract.MovieEntry.COL_VOTE_AVERAGE + " REAL NOT NULL, " +
            MovieContract.MovieEntry.COL_VOTE_COUNT + " INTEGER NOT NULL, " +
            MovieContract.MovieEntry.COL_POSTER_PATH + " TEXT NOT NULL, "  +
            MovieContract.MovieEntry.COL_DATE + " TEXT NOT NULL, " +

            // Set up the location column as a foreign key to location table.
            " FOREIGN KEY (" + MovieContract.MovieEntry.COL_MOVIE_KEY + ") REFERENCES " +
            MovieContract.MovieSettings.TABLE_NAME + " (" + MovieContract.MovieSettings._ID + "), " +

            // To assure the application have just one weather entry per day
            // per location, it's created a UNIQUE constraint with REPLACE strategy
            " UNIQUE (" + MovieContract.MovieEntry.COL_DATE + ", " +
            MovieContract.MovieEntry.COL_MOVIE_KEY + ") ON CONFLICT REPLACE);";


    sqLiteDatabase.execSQL(SQL_CREATE_MOVIE__SETTING_TABLE);
    sqLiteDatabase.execSQL(SQL_CREATE_MOVIE_TABLE);

}


@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
    // This database is only a cache for online data, so its upgrade policy is
    // to simply to discard the data and start over
    // Note that this only fires if you change the version number for your database.
    // It does NOT depend on the version number for your application.
    // If you want to update the schema without wiping data, commenting out the next 2 lines
    // should be your top priority before modifying this method.

    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + MovieContract.MovieSettings.TABLE_NAME);

    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + MovieContract.MovieEntry.TABLE_NAME);
    onCreate(sqLiteDatabase);
}
}

所有空格似乎都是正确的 我通过内容提供商阅读存储的数据。

package tziomakas.theo.popularmoviespart2.data;

                import android.annotation.TargetApi;
                import android.content.ContentProvider;
                import android.content.ContentValues;
                import android.content.UriMatcher;
                import android.database.Cursor;
                import android.database.sqlite.SQLiteDatabase;
                import android.database.sqlite.SQLiteQueryBuilder;
                import android.net.Uri;
                import android.support.annotation.NonNull;
                import android.support.annotation.Nullable;

                /**
                 * Created by theodosiostziomakas on 04/11/2017.
                 */

                public class MovieProvider extends ContentProvider {
                    private static final UriMatcher sUriMatcher = buildUriMatcher();
                    public static final int MOVIE = 100;
                    public static final int MOVIE_WITH_SETTING = 101;
                    public static final int MOVIE_WITH_SETTING_AND_DATE = 102;
                    public static final int SETTING = 200;
                    private static final SQLiteQueryBuilder sMovieBySettingQueryBuilder;
                    private MoviesDbHelper mOpenHelper;
                    static{
                        sMovieBySettingQueryBuilder = new SQLiteQueryBuilder();

                        //This is an inner join which looks like
                        //weather INNER JOIN location ON weather.location_id = location._id
                        sMovieBySettingQueryBuilder.setTables(
                                MovieContract.MovieEntry.TABLE_NAME + "INNER JOIN" +
                                MovieContract.MovieSettings.TABLE_NAME + "ON" +
                                MovieContract.MovieEntry.TABLE_NAME  + "." + MovieContract.MovieEntry.COL_MOVIE_KEY + " = " +
                                MovieContract.MovieSettings.TABLE_NAME + MovieContract.MovieSettings._ID);
                        }

                    //movie_setting.settings = ?
                    private static final String sMovieSettingSelection =
                            MovieContract.MovieSettings.TABLE_NAME+
                                    "." + MovieContract.MovieSettings.COL_MOVIE_SETTING + " = ? ";

                    //movie_setting.settings = ? AND date => ?
                    private static final String sMovieSettingWithStartDateSelection =
                            MovieContract.MovieSettings.TABLE_NAME+
                                    "." + MovieContract.MovieSettings.COL_MOVIE_SETTING + " = ? AND " +
                                    MovieContract.MovieEntry.COL_DATE + " >= ? ";

                    //movie_setting.settings = ? AND date = ?
                    private static final String sMovieSettingAndDateSelection =
                            MovieContract.MovieSettings.TABLE_NAME+
                                    "." + MovieContract.MovieSettings.COL_MOVIE_SETTING + " = ? AND " +
                                    MovieContract.MovieEntry.COL_DATE + " = ? ";



                    public Cursor getMovieBySetting(Uri uri, String[] projection, String sortOrder){
                        String movieSetting = MovieContract.MovieEntry.getMovieSettingFromUri(uri);


                        String [] selectionArgs;
                        String selection;


                            selection = sMovieSettingSelection;
                            selectionArgs = new String[]{movieSetting};


                        return sMovieBySettingQueryBuilder.query(mOpenHelper.getReadableDatabase(),
                                projection,
                                selection,
                                selectionArgs,
                                null,
                                null,
                                sortOrder);

                    }
                    static UriMatcher buildUriMatcher() {
                        // I know what you're thinking.  Why create a UriMatcher when you can use regular
                        // expressions instead?  Because you're not crazy, that's why.

                        // All paths added to the UriMatcher have a corresponding code to return when a match is
                        // found.  The code passed into the constructor represents the code to return for the root
                        // URI.  It's common to use NO_MATCH as the code for this case.
                        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
                        final String authority = MovieContract.CONTENT_AUTHORITY;

                        // For each type of URI you want to add, create a corresponding code.
                        matcher.addURI(authority, MovieContract.PATH_MOVIES, MOVIE);
                        matcher.addURI(authority, MovieContract.PATH_MOVIES + "/*", MOVIE_WITH_SETTING);

                        matcher.addURI(authority, MovieContract.PATH_MOVIE_SETTINGS, SETTING);
                        return matcher;
                    }

                    @Override
                    public boolean onCreate() {
                        mOpenHelper = new MoviesDbHelper(getContext());
                        return true;
                    }

                    @Override
                    public Cursor query( Uri uri,  String[] projection, String selection,  String[] selectionArgs,  String sortOrder) {
                        // Here's the switch statement that, given a URI, will determine what kind of request it is,
                        // and query the database accordingly.
                        Cursor retCursor;
                        switch (sUriMatcher.match(uri)){

                            case MOVIE_WITH_SETTING:{
                                retCursor = getMovieBySetting(uri,projection,sortOrder);
                                break;
                            }

                            case MOVIE:{
                               retCursor = mOpenHelper.getReadableDatabase().query(
                                       MovieContract.MovieEntry.TABLE_NAME,
                                       projection,
                                       selection,
                                       selectionArgs,
                                       null,
                                       null,
                                       sortOrder
                               );
                               break;
                            }
                            case SETTING:{
                                retCursor = mOpenHelper.getReadableDatabase().query(
                                        MovieContract.MovieSettings.TABLE_NAME,
                                        projection,
                                        selection,
                                        selectionArgs,
                                        null,
                                        null,
                                        sortOrder
                                );
                                break;
                            }
                            default:
                                throw new UnsupportedOperationException("Unknown uri: " + uri);

                        }

                        retCursor.setNotificationUri(getContext().getContentResolver(), uri);
                        return retCursor;
                    }

                    @Override
                    public String getType(Uri uri) {

                        // Use the Uri Matcher to determine what kind of URI this is.
                        final int match = sUriMatcher.match(uri);

                        switch (match) {
                            // Student: Uncomment and fill out these two cases
                            case MOVIE_WITH_SETTING_AND_DATE:
                                return MovieContract.MovieEntry.CONTENT_ITEM_TYPE;
                            case MOVIE_WITH_SETTING:
                                return MovieContract.MovieEntry.CONTENT_TYPE;
                            case MOVIE:
                                return MovieContract.MovieEntry.CONTENT_TYPE;
                            case SETTING:
                                return MovieContract.MovieSettings.CONTENT_TYPE;
                            default:
                                throw new UnsupportedOperationException("Unknown uri: " + uri);
                        }
                    }

                    @Override
                    public Uri insert(Uri uri, ContentValues values) {
                        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
                        final int match = sUriMatcher.match(uri);
                        Uri returnUri;

                        switch (match) {
                            case MOVIE: {
                                normalizeDate(values);
                                long _id = db.insert(MovieContract.MovieEntry.TABLE_NAME, null, values);
                                if ( _id > 0 )
                                    returnUri = MovieContract.MovieEntry.buildMovieUri(_id);
                                else
                                    throw new android.database.SQLException("Failed to insert row into " + uri);
                                break;
                            }
                            case SETTING: {
                                long _id = db.insert(MovieContract.MovieSettings.TABLE_NAME, null, values);
                                if ( _id > 0 )
                                    returnUri = MovieContract.MovieSettings.buildMovieSettingUri(_id);
                                else
                                    throw new android.database.SQLException("Failed to insert row into " + uri);
                                break;
                            }
                            default:
                                throw new UnsupportedOperationException("Unknown uri: " + uri);
                        }
                        getContext().getContentResolver().notifyChange(uri, null);
                        return returnUri;
                    }

                    @Override
                    public int delete(Uri uri, String selection, String[] selectionArgs) {
                        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
                        final int match = sUriMatcher.match(uri);
                        int rowsDeleted;
                        // this makes delete all rows return the number of rows deleted
                        if ( null == selection ) selection = "1";
                        switch (match) {
                            case MOVIE:
                                rowsDeleted = db.delete(
                                        MovieContract.MovieEntry.TABLE_NAME, selection, selectionArgs);
                                break;
                            case SETTING:
                                rowsDeleted = db.delete(
                                        MovieContract.MovieSettings.TABLE_NAME, selection, selectionArgs);
                                break;
                            default:
                                throw new UnsupportedOperationException("Unknown uri: " + uri);
                        }
                        // Because a null deletes all rows
                        if (rowsDeleted != 0) {
                            getContext().getContentResolver().notifyChange(uri, null);
                        }
                        return rowsDeleted;
                    }

                    @Override
                    public int update(
                            Uri uri, ContentValues values, String selection, String[] selectionArgs) {
                        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
                        final int match = sUriMatcher.match(uri);
                        int rowsUpdated;

                        switch (match) {

                            case MOVIE:
                                normalizeDate(values);
                                rowsUpdated = db.update(MovieContract.MovieEntry.TABLE_NAME,values, selection, selectionArgs);
                                break;
                            case SETTING:
                                rowsUpdated = db.update(MovieContract.MovieSettings.TABLE_NAME, values, selection,
                                        selectionArgs);
                                break;
                            default:
                                throw new UnsupportedOperationException("Unknown uri: " + uri);
                        }
                        if (rowsUpdated != 0) {
                            getContext().getContentResolver().notifyChange(uri, null);
                        }
                        return rowsUpdated;
                    }

                    private void normalizeDate(ContentValues values) {
                        // normalize the date value
                        if (values.containsKey(MovieContract.MovieEntry.COL_DATE)) {
                            long dateValue = values.getAsLong(MovieContract.MovieEntry.COL_DATE);
                            values.put(MovieContract.MovieEntry.COL_DATE, MovieContract.normalizeDate(dateValue));
                        }
                    }
                    @Override
                    public int bulkInsert(Uri uri, ContentValues[] values) {
                        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
                        final int match = sUriMatcher.match(uri);
                        switch (match) {
                            case MOVIE:
                                db.beginTransaction();
                                int returnCount = 0;
                                try {
                                    for (ContentValues value : values) {
                                        normalizeDate(value);
                                        long _id = db.insert(MovieContract.MovieEntry.TABLE_NAME, null, value);
                                        if (_id != -1) {
                                            returnCount++;
                                        }
                                    }
                                    db.setTransactionSuccessful();
                                } finally {
                                    db.endTransaction();
                                }
                                getContext().getContentResolver().notifyChange(uri, null);
                                return returnCount;
                            default:
                                return super.bulkInsert(uri, values);
                        }
                    }

                    // You do not need to call this method. This is a method specifically to assist the testing
                    // framework in running smoothly. You can read more at:
                    // http://developer.android.com/reference/android/content/ContentProvider.html#shutdown()
                    @Override
                    @TargetApi(11)
                    public void shutdown() {
                        mOpenHelper.close();
                        super.shutdown();
                    }
                }

这些代码行给出了以下错误。

 //movie_setting.settings = ?
                    private static final String sMovieSettingSelection =
                            MovieContract.MovieSettings.TABLE_NAME+
                                    "." + MovieContract.MovieSettings.COL_MOVIE_SETTING + " = ? ";


near ".": syntax error

您看到的问号是选择值 在我的例子中,它是一个名为popular的字符串。

0 个答案:

没有答案