删除或通过数据库进行搜索时出现奇怪结果

huangapple go评论89阅读模式
英文:

Weird result when deleting or searching through database

问题

以下是翻译好的部分:

我正在学习如何在Android Studio中使用SQLite,并在尝试从数据库中删除数据时遇到了一个奇怪的问题。该表当前跟踪三种数据,其中一种是整数,另外两种是字符串。当我尝试删除数据时,我只传递这两个字符串,因为我实际上不需要ID。如果这两个字符串中包含任何字母,程序就会失败,但如果只包含数字,那么它就可以正常工作。例如,如果我尝试删除具有字符串"456"和"654"的数据,它将能够找到并删除,但如果我尝试"Book"和"Pen"这样的字符串,就会失败。

此外,当我在数据库中进行全局搜索时,它可以正常工作,但如果我进行更具体的搜索,就会失败,我不确定原因。这是我的DataBaseHelper类中的代码:

public void RemoveOne(GameInformation gameInformation) {
    SQLiteDatabase db = this.getWritableDatabase();
    String queryString = "delete from " + GAME_TABLE +
            " where " + COLUMN_GAME_NAME + " like " + gameInformation.getName() +
            " and " + COLUMN_GAME_PLATFORM + " like " + gameInformation.getPlatform();
    db.execSQL(queryString);
    db.close();
}

public List<GameInformation> GetEverything() {
    String queryString = "select * from " + GAME_TABLE;
    return AddDbToArray(queryString);
}

public List<GameInformation> Search(GameInformation gameInformation) {
    String queryString = "select * from " + GAME_TABLE + " where " + COLUMN_GAME_NAME + " like " + gameInformation.getName();
    return AddDbToArray(queryString);
}

private List<GameInformation> AddDbToArray(String queryString) {
    List<GameInformation> returnList = new ArrayList<>();
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(queryString, null);
    if (cursor.moveToFirst()) {
        do {
            int gameID = cursor.getInt(0);
            String gameName = cursor.getString(1);
            String platform = cursor.getString(2);
            GameInformation gameInformation = new GameInformation(gameID, gameName, platform);
            returnList.add(gameInformation);
        } while (cursor.moveToNext());
    } else {

    }
    cursor.close();
    db.close();
    return returnList;
}

这是我的MainActivity类中的代码:

removeBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String gameInput = gameTxt.getText().toString();
        String platformInput = platformTxt.getText().toString();

        GameInformation gameInformation = null;
        try {
            if (!gameInput.equalsIgnoreCase("") && !platformInput.equalsIgnoreCase("")) {
                gameInformation = new GameInformation(-1, gameInput, platformInput);
            } else {
                Toast.makeText(MainActivity.this, "您遗漏了一些信息", Toast.LENGTH_SHORT).show();
                return;
            }
            dataBaseHelper.RemoveOne(gameInformation);
        } catch (Exception e) {
            Toast.makeText(MainActivity.this, "某些内容失败 " + gameInformation.getName(), Toast.LENGTH_SHORT).show();
        }
        ShowGamesOnListView(dataBaseHelper);
    }
});
viewBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        dataBaseHelper = new DataBaseHelper(MainActivity.this);
        ShowGamesOnListView(dataBaseHelper);
    }
});

searchBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        dataBaseHelper = new DataBaseHelper(MainActivity.this);
        GameInformation gameInformation = null;
        String platformName = platformTxt.getText().toString();
        String gameName = gameTxt.getText().toString();
        gameInformation = new GameInformation(-1, gameName, platformName);
        try {
            ShowSearchResultListView(dataBaseHelper, gameInformation);
        } catch (Exception e) {
            Toast.makeText(MainActivity.this, "搜索 " + gameName + " 时出错", Toast.LENGTH_SHORT).show();
        }
    }
});
}

private void ShowSearchResultListView(DataBaseHelper dataBaseHelper, GameInformation gameInformation) {
    gameArrayAdaptor = new ArrayAdapter<GameInformation>(MainActivity.this, android.R.layout.simple_list_item_1, dataBaseHelper.Search(gameInformation));
    dbList.setAdapter(gameArrayAdaptor);
}

private void ShowGamesOnListView(DataBaseHelper dataBaseHelper) {
    gameArrayAdaptor = new ArrayAdapter<GameInformation>(MainActivity.this, android.R.layout.simple_list_item_1, dataBaseHelper.GetEverything());
    dbList.setAdapter(gameArrayAdaptor);
}

对于您的代码,我看到了一些可能导致问题的地方,但没有足够的上下文来进行详细的分析。如果您遇到问题,可能是因为查询字符串中的字符串值未用引号包裹,这可能导致数据库查询失败。确保在构建查询字符串时,为字符串值添加引号。另外,如果可能的话,最好使用参数化查询来避免SQL注入和其他问题。还有其他一些潜在的问题,但没有足够的信息来进行准确的指导。如果您可以提供更多的信息,我将能够为您提供更具体的建议。

英文:

I'm learning how to use SQLite within Android studio and came across a weird issue when trying to delete things from the database. The table currently keeps track of three things, one is an int, and the other two are strings. When I try to delete, I pass the two strings only, since I don't really need the ID. If the strings contain any letters at all, the program fails, but if it consists of only numbers then it works perfectly. For example, if I try to delete something with the strings 456 and 654, then it will find and erase it, but if I try "Book" and "Pen", then it fails.

Also, when I'm searching through the database, if I search for everything at once, it works, but if I make the search more specific, it fails, and I'm not sure why. This is the code in my DataBaseHelper class:

public void RemoveOne(GameInformation gameInformation) {
SQLiteDatabase db = this.getWritableDatabase();
String queryString = &quot;delete from &quot; + GAME_TABLE +
&quot; where &quot; + COLUMN_GAME_NAME + &quot; like &quot; + gameInformation.getName() +
&quot; and &quot; + COLUMN_GAME_PLATFORM + &quot; like &quot; + gameInformation.getPlatform();
db.execSQL(queryString);
db.close();
}
public List&lt;GameInformation&gt; GetEverything() {
String queryString = &quot;select * from &quot; + GAME_TABLE;
return AddDbToArray(queryString);
}
public List&lt;GameInformation&gt; Search(GameInformation gameInformation) {
String queryString = &quot;select * from &quot; + GAME_TABLE + &quot; where &quot; + COLUMN_GAME_NAME + &quot; like &quot; + gameInformation.getName();
return AddDbToArray(queryString);
}
private List&lt;GameInformation&gt; AddDbToArray(String queryString) {
List&lt;GameInformation&gt; returnList = new ArrayList&lt;&gt;();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(queryString, null);
if (cursor.moveToFirst()) {
do {
int gameID = cursor.getInt(0);
String gameName = cursor.getString(1);
String platform = cursor.getString(2);
GameInformation gameInformation = new GameInformation(gameID, gameName, platform);
returnList.add(gameInformation);
}
while (cursor.moveToNext());
} else {
}
cursor.close();
db.close();
return returnList;
}

And this is the code in my MainActivity class:

    removeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String gameInput = gameTxt.getText().toString();
String platformInput = platformTxt.getText().toString();
GameInformation gameInformation = null;
try {
if (!gameInput.equalsIgnoreCase(&quot;&quot;) &amp;&amp; !platformInput.equalsIgnoreCase(&quot;&quot;)) {
gameInformation = new GameInformation(-1, gameInput, platformInput);
} else {
Toast.makeText(MainActivity.this, &quot;You missed some information&quot;, Toast.LENGTH_SHORT).show();
return;
}
dataBaseHelper.RemoveOne(gameInformation);
} catch (Exception e) {
Toast.makeText(MainActivity.this, &quot;Something failed &quot; + gameInformation.getName(), Toast.LENGTH_SHORT).show();
}
ShowGamesOnListView(dataBaseHelper);
}
});
viewBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dataBaseHelper = new DataBaseHelper(MainActivity.this);
ShowGamesOnListView(dataBaseHelper);
}
});
searchBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dataBaseHelper = new DataBaseHelper(MainActivity.this);
GameInformation gameInformation = null;
String platformName = platformTxt.getText().toString();
String gameName = gameTxt.getText().toString();
gameInformation = new GameInformation(-1, gameName, platformName);
try {
ShowSearchResultListView(dataBaseHelper, gameInformation);
} catch (Exception e) {
Toast.makeText(MainActivity.this, &quot;Something went wrong with &quot; + gameName, Toast.LENGTH_SHORT).show();
}
}
});
}
private void ShowSearchResultListView(DataBaseHelper dataBaseHelper, GameInformation gameInformation) {
gameArrayAdaptor = new ArrayAdapter&lt;GameInformation&gt;(MainActivity.this, android.R.layout.simple_list_item_1, dataBaseHelper.Search(gameInformation));
dbList.setAdapter(gameArrayAdaptor);
}
private void ShowGamesOnListView(DataBaseHelper dataBaseHelper) {
gameArrayAdaptor = new ArrayAdapter&lt;GameInformation&gt;(MainActivity.this, android.R.layout.simple_list_item_1, dataBaseHelper.GetEverything());
dbList.setAdapter(gameArrayAdaptor);
}

Any advice on what I'm getting wrong?

答案1

得分: 1

我认为这里出现问题的是一个未知引用。

这是您的查询定义:

        String queryString = "delete from " + GAME_TABLE +
                " where " + COLUMN_GAME_NAME + " like " + gameInformation.getName() +
                " and " + COLUMN_GAME_PLATFORM + " like " + gameInformation.getPlatform();

在编写 SQL 语句时,语法类似于 这样

SELECT column1, column2, ...
FROM table_name
WHERE columnN LIKE pattern;

对于 pattern 占位符,您需要编写类似这样的内容:

WHERE CustomerName LIKE 'a%'	-- 查找任何以 'a' 开头的值

请注意有一些单引号 ''

因此,在 Android 中,我们不能像在命令行上那样编写 SQL 代码。实际上,我们在 Java(或 Kotlin)中编写一个完全遵循 SQL 语法的字符串。
最终,它仍然是一个字符串。

您正在这样添加字符串:

String queryString = "select * from " + GAME_TABLE + " where " + COLUMN_GAME_NAME + " like " + gameInformation.getName();

其中

String gameName = gameTxt.getText().toString();

您正在将字符串连接到一个字符串中,最终看起来类似于:

String queryString = "SELECT * FROM game_table_entity_name WHERE column_name LIKE ExampleName;";

实际上,它应该看起来像这样:

String queryString = "SELECT * FROM game_table_entity_name WHERE column_name LIKE 'ExampleName';";

因此,在连接带有双引号的字符串时,请不要忘记添加单引号。
在 SQL 语法中,应该是字符串的所有内容都需要包裹在这些“嵌套”的引号中。

不管怎样,使用 Room 持久性库是推荐的方法,用于在内部 SQLite 数据库中持久保存应用程序数据。

英文:

I assume what is failing here is an unknown reference.

This is your query definition:

        String queryString = &quot;delete from &quot; + GAME_TABLE +
&quot; where &quot; + COLUMN_GAME_NAME + &quot; like &quot; + gameInformation.getName() +
&quot; and &quot; + COLUMN_GAME_PLATFORM + &quot; like &quot; + gameInformation.getPlatform();

When writing a SQL statement, the syntax looks like this:

SELECT column1, column2, ...
FROM table_name
WHERE columnN LIKE pattern;

For the pattern placeholder you need to write something like this:

WHERE CustomerName LIKE &#39;a%&#39;	// Finds any values that start with &quot;a&quot;

Note that there are some '' single quotation marks.
So inside an SQL query you have to write a string in some kind of string notation.

Now in Android we can not write SQL code like on a command line. So actually we are writing a string in Java (or Kotlin) that exactly follows the SQL syntax.
In the end, it is still a string.

You are adding strings like this:

String queryString = &quot;select * from &quot; + GAME_TABLE + &quot; where &quot; + COLUMN_GAME_NAME + &quot; like &quot; + gameInformation.getName();

Where

String gameName = gameTxt.getText().toString();

You are concatenating strings to a string which in the end looks similar to this:

String queryString = &quot;SELECT * FROM game_table_entity_name WHERE column_name LIKE ExampleName;&quot;

Where it actually should look like this:

String queryString = &quot;SELECT * FROM game_table_entity_name WHERE column_name LIKE &#39;ExampleName&#39;;&quot;

So do not forget to add the single quotation marks when you are concatenating strings with double quotation marks.
Everything that should be a string (in SQL syntax) needs to be wrapped into these "nested" quotation marks.

Anyways, using the Room Persistence Library is the recommended way to persist app data with an internal SQLite database.

huangapple
  • 本文由 发表于 2020年8月28日 03:30:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63622991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定