While not as powerful as SQL, Azure tables do allow you to do minimal querying. With the native SDK, you’d do this using the table_query object’s set_filter_string function. Here’s a modified ReadTableData method from the previous blog entries.
void ReadTableData(string_t filter)
{
auto storage_account = cloud_storage_account::parse(
U("UseDevelopmentStorage=true"));
auto table_client = storage_account.create_cloud_table_client();
auto table = table_client.get_table_reference(U("Clients"));
bool created = table.create_if_not_exists();
table_query query;
query.set_filter_string(filter);
auto results = table.execute_query(query);
for (auto item : results)
{
auto properties = item.properties();
for (auto property : properties)
{
ucout << property.first << U(" = ")
<< property.second.str() << U("\t");
}
ucout << endl;
}
}
Here’s an example query that gets all rows within a range of RowKey values.
void ReadTableData(string_t rowKeyStart, string_t rowKeyEnd)
{
auto filter = table_query::combine_filter_conditions(
table_query::generate_filter_condition(
U("RowKey"),
query_comparison_operator::greater_than_or_equal,
rowKeyStart),
query_logical_operator::and,
table_query::generate_filter_condition(
U("RowKey"),
query_comparison_operator::less_than_or_equal,
rowKeyEnd));
ReadTableData(filter);
}
The combine_filter_conditions function is used to create a query string. The query_comparison_operator class allows you to set comparison operators and the query_logical_operator class lets you set logical operators. In case you are wondering, that gets converted to the following string.
(RowKey ge ‘100’) and (RowKey le ‘104’)
Here’s a similar method, that queries against the Name column.
void ReadTableDataStartingWith(string_t letter1, string_t letter2)
{
auto filter = table_query::combine_filter_conditions(
table_query::generate_filter_condition(
U("Name"),
query_comparison_operator::greater_than_or_equal,
letter1),
query_logical_operator::and,
table_query::generate_filter_condition(
U("Name"),
query_comparison_operator::less_than,
letter2));
ReadTableData(filter);
}
The generated query filter looks like this.
(Name ge ‘D’) and (Name lt ‘E’)
You can call it as follows :
ReadTableDataStartingWith(U("D"), U("E"));
That’d return all rows with names starting with a D. Querying against partition and row keys would be a faster approach. Also, for repeated querying against a set of data, you may want to fetch a larger subset of the data and then query it in memory using standard STL.