SQLite rawQuery + String.format = "The statement has 0 parameters."?
SQLite rawQuery + String.format = "The statement has 0 parameters."?
我正在尝试在 android 中执行 sqlite rawquery。我从我的设备上下载了数据库,并使用 "sqlite query browser" windows 程序试错,直到我得到我想要的。现在的问题是我有我需要的字符串,我似乎无法将参数输入其中,我怀疑它只是某种字符串转义缺陷。
我要执行的查询是
SELECT lis.name from listItemSuggestion lis LEFT JOIN listItem li ON lis.name = li.name WHERE li.name is NULL AND lis.name LIKE '%a%'
其中“%a%”中的 a 需要是可变参数。我在代码中所做的是这样的:
getReadableDatabase().rawQuery(
String.format("SELECT lis.%s from %s lis LEFT JOIN %s li ON lis.%s = li.%s WHERE li.%s is NULL AND lis.%s LIKE '%%?%%';",
ListItemSuggestion.COLUMN_NAME,
ListItemSuggestion.TABLE_NAME,
ListItem.TABLE_NAME,
ListItemSuggestion.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItemSuggestion.COLUMN_NAME
),
new String[]{filter}
);
合同类是:
import android.provider.BaseColumns;
public final class ListItem {
private ListItem(){}
public static class ListItemEntry implements BaseColumns
{
public static final String TABLE_NAME = "listItem";
public static final String COLUMN_DONE = "done";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_COUNT = "count";
public static final String COLUMN_TIMESTAMP = "timestamp";
}
}
import android.provider.BaseColumns;
public final class ListItemSuggestion {
private ListItemSuggestion(){}
public static class ListItemSuggestionEntry implements BaseColumns
{
public static final String TABLE_NAME = "listItemSuggestion";
public static final String COLUMN_NAME = "name";
}
}
我得到的错误是:
无法在索引 1 处绑定参数,因为索引超出范围。该语句有 0 个参数。 (这意味着它没有在查询中找到“?”,对吗?虽然有一个......,顺便说一句 "filter" 是一个方法参数)
顺便说一句:该查询的目的是为列表项动态的输入提供建议(= 在 list/table 上,它们可以随时从中删除),同时每个项目也会静默创建建议项目(在另一个 table 中)在实际项目被删除时不会被删除。 where 子句应获取与当前文本输入状态匹配的建议,并排除已在列表中的项目。
不知道你怎么看:
'%%?%%'
可以,但您必须将其更改为串联 '%' || ? || '%'
:
getReadableDatabase().rawQuery(
String.format("SELECT lis.%s from %s lis LEFT JOIN %s li ON lis.%s = li.%s WHERE li.%s is NULL AND lis.%s LIKE '%' || ? || '%';",
ListItemSuggestion.COLUMN_NAME,
ListItemSuggestion.TABLE_NAME,
ListItem.TABLE_NAME,
ListItemSuggestion.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItemSuggestion.COLUMN_NAME
),
new String[]{filter}
);
Cannot bind argument at index 1 because the index is out of range. The statement has 0 parameters. (Meaning its not finding the "?" in the query, right?
不完全是。
though there is one..., btw "filter" is a method argument)
问题是问号在带引号的字符串内。这使它成为纯文本,而不是参数占位符。这种变体似乎是您要找的:
getReadableDatabase().rawQuery(
String.format("SELECT lis.%s from %s lis LEFT JOIN %s li ON lis.%s = li.%s WHERE li.%s is NULL AND lis.%s LIKE ?;",
ListItemSuggestion.COLUMN_NAME,
ListItemSuggestion.TABLE_NAME,
ListItem.TABLE_NAME,
ListItemSuggestion.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItemSuggestion.COLUMN_NAME
),
new String[]{ "%" + filter + "%" }
);
完全不相关,但是如果您使用字符串连接,SQL 会更容易阅读:
getReadableDatabase().rawQuery(
"SELECT lis." + ListItemSuggestion.COLUMN_NAME +
" FROM " + ListItemSuggestion.TABLE_NAME + " lis" +
" LEFT JOIN " + ListItem.TABLE_NAME + " li" +
" ON li." + ListItem.COLUMN_NAME + " = lis." + ListItemSuggestion.COLUMN_NAME +
" WHERE li." + ListItem.COLUMN_NAME + " IS NULL" +
" AND lis." + ListItemSuggestion.COLUMN_NAME + " LIKE ?",
new String[] { "%" + filter + "%" }
);
实际上,您只使用 li
进行存在性检查,所以这样写:
getReadableDatabase().rawQuery(
"SELECT " + ListItemSuggestion.COLUMN_NAME +
" FROM " + ListItemSuggestion.TABLE_NAME +
" WHERE " + ListItemSuggestion.COLUMN_NAME + " LIKE ?" +
" AND " + ListItemSuggestion.COLUMN_NAME + " NOT IN (" +
" SELECT li." + ListItem.COLUMN_NAME +
" FROM " + ListItem.TABLE_NAME + " li )",
new String[] { "%" + filter + "%" }
);
我正在尝试在 android 中执行 sqlite rawquery。我从我的设备上下载了数据库,并使用 "sqlite query browser" windows 程序试错,直到我得到我想要的。现在的问题是我有我需要的字符串,我似乎无法将参数输入其中,我怀疑它只是某种字符串转义缺陷。
我要执行的查询是
SELECT lis.name from listItemSuggestion lis LEFT JOIN listItem li ON lis.name = li.name WHERE li.name is NULL AND lis.name LIKE '%a%'
其中“%a%”中的 a 需要是可变参数。我在代码中所做的是这样的:
getReadableDatabase().rawQuery(
String.format("SELECT lis.%s from %s lis LEFT JOIN %s li ON lis.%s = li.%s WHERE li.%s is NULL AND lis.%s LIKE '%%?%%';",
ListItemSuggestion.COLUMN_NAME,
ListItemSuggestion.TABLE_NAME,
ListItem.TABLE_NAME,
ListItemSuggestion.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItemSuggestion.COLUMN_NAME
),
new String[]{filter}
);
合同类是:
import android.provider.BaseColumns;
public final class ListItem {
private ListItem(){}
public static class ListItemEntry implements BaseColumns
{
public static final String TABLE_NAME = "listItem";
public static final String COLUMN_DONE = "done";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_COUNT = "count";
public static final String COLUMN_TIMESTAMP = "timestamp";
}
}
import android.provider.BaseColumns;
public final class ListItemSuggestion {
private ListItemSuggestion(){}
public static class ListItemSuggestionEntry implements BaseColumns
{
public static final String TABLE_NAME = "listItemSuggestion";
public static final String COLUMN_NAME = "name";
}
}
我得到的错误是:
无法在索引 1 处绑定参数,因为索引超出范围。该语句有 0 个参数。 (这意味着它没有在查询中找到“?”,对吗?虽然有一个......,顺便说一句 "filter" 是一个方法参数)
顺便说一句:该查询的目的是为列表项动态的输入提供建议(= 在 list/table 上,它们可以随时从中删除),同时每个项目也会静默创建建议项目(在另一个 table 中)在实际项目被删除时不会被删除。 where 子句应获取与当前文本输入状态匹配的建议,并排除已在列表中的项目。
不知道你怎么看:
'%%?%%'
可以,但您必须将其更改为串联 '%' || ? || '%'
:
getReadableDatabase().rawQuery(
String.format("SELECT lis.%s from %s lis LEFT JOIN %s li ON lis.%s = li.%s WHERE li.%s is NULL AND lis.%s LIKE '%' || ? || '%';",
ListItemSuggestion.COLUMN_NAME,
ListItemSuggestion.TABLE_NAME,
ListItem.TABLE_NAME,
ListItemSuggestion.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItemSuggestion.COLUMN_NAME
),
new String[]{filter}
);
Cannot bind argument at index 1 because the index is out of range. The statement has 0 parameters. (Meaning its not finding the "?" in the query, right?
不完全是。
though there is one..., btw "filter" is a method argument)
问题是问号在带引号的字符串内。这使它成为纯文本,而不是参数占位符。这种变体似乎是您要找的:
getReadableDatabase().rawQuery(
String.format("SELECT lis.%s from %s lis LEFT JOIN %s li ON lis.%s = li.%s WHERE li.%s is NULL AND lis.%s LIKE ?;",
ListItemSuggestion.COLUMN_NAME,
ListItemSuggestion.TABLE_NAME,
ListItem.TABLE_NAME,
ListItemSuggestion.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItem.COLUMN_NAME,
ListItemSuggestion.COLUMN_NAME
),
new String[]{ "%" + filter + "%" }
);
完全不相关,但是如果您使用字符串连接,SQL 会更容易阅读:
getReadableDatabase().rawQuery(
"SELECT lis." + ListItemSuggestion.COLUMN_NAME +
" FROM " + ListItemSuggestion.TABLE_NAME + " lis" +
" LEFT JOIN " + ListItem.TABLE_NAME + " li" +
" ON li." + ListItem.COLUMN_NAME + " = lis." + ListItemSuggestion.COLUMN_NAME +
" WHERE li." + ListItem.COLUMN_NAME + " IS NULL" +
" AND lis." + ListItemSuggestion.COLUMN_NAME + " LIKE ?",
new String[] { "%" + filter + "%" }
);
实际上,您只使用 li
进行存在性检查,所以这样写:
getReadableDatabase().rawQuery(
"SELECT " + ListItemSuggestion.COLUMN_NAME +
" FROM " + ListItemSuggestion.TABLE_NAME +
" WHERE " + ListItemSuggestion.COLUMN_NAME + " LIKE ?" +
" AND " + ListItemSuggestion.COLUMN_NAME + " NOT IN (" +
" SELECT li." + ListItem.COLUMN_NAME +
" FROM " + ListItem.TABLE_NAME + " li )",
new String[] { "%" + filter + "%" }
);