[odb-users] Queries matching on NVARCHAR fields fail to return records when using "short data"

Oded Arbel oded at geek.co.il
Thu Oct 4 17:56:09 EDT 2012

Hi guys.

I'm using MS-SQL Server 2008, and I noticed that when I use queries
that match on NVARCHAR fields, the matching always fails if the field
is short enough to be considered "short data" (according to section
17.1 of the manual).

My model class looks something like this:

typedef std::wstring short_string;
#pragma db value(short_string) type("NVARCHAR(36)")
typedef std::wstring long_text;
#pragma db value(long_text) type("NVARCHAR(MAX)")

namespace model {
	#pragma db object table("some_item")
	class SomeItem
		~SomeItem() {}
		SomeItem(unsigned int otheritem):_id(0) { }

		// getters, setters, business logic etc..

		unsigned int _id;
		unsigned int id() const { return _id; };

	private: // serialization support
		friend class odb::access;
		#pragma db member(_id) id auto column("job_item_id")
		#pragma db column("other_item_id")
		std::shared_ptr<OtherItem> _otheritem;

		short_string _uuid;
		odb::nullable<long_string> _fqdn;
		int _state;
		#pragma db type("NVARCHAR(128)")
		odb::nullable<std::wstring> _name;

And my query looks something like this:

std::vector<std::shared_ptr<SomeItem>> getStuff(unsigned int otherId,
const std::wstring& someName) {
	typedef odb::query<SomeItem> query;
	try {
		std::vector<std::shared_ptr<SomeItem>> out;
		odb::transaction t(getDB()->begin());
		odb::result<SomeItem> rs(getDB()->query<SomeItem>(query::otheritem
== query::_val(otherId)
			&& query::name == someName
			&& query::state == query::_val(SOME_KNOWN_STATE) ));
		for (auto it(rs.begin()); it != rs.end(); ++it) {
			out.push_back(std::shared_ptr<SomeItem>(new SomeItem(*it)));
		return out;
	} catch (const odb::exception &e) {
		// handle errors

(There are  few peculiarities in this code which I would be happy to
discuss as well, but more on that later).

Now with the default setting, this query always returns an empty list
even though all the fields are properly populated in the database.
I've tried commenting out the query::name part, and then it returns
what I expect. I also tried _val and _ref for matching on the item
name, but to no avail. After I rebuilt the ODB implementation using
--mssql-short-limit 100, it started working - now queries that match
on name return the expected results.

But matching on "uuid" (which is a "short string" so should use short
data even with the new setting), indeed still fails.

Is there something obvious I'm missing here?


More information about the odb-users mailing list