在sqlite3语句中绑定'unsigned long'(uint64)?C++

g19*_*tic 16 c++ sqlite bind unsigned-integer

我正在使用sqlite.org上提供的sqlite3库.

我有一些我想要存储在数据库中的unsigned longs.我不想自己构建查询并将其保持开放以进行某种注入(无论是否是偶然的).因此,我正在使用这些sqlite_bind_*函数来"清理"我的参数.

问题是对于无符号长整数,只有整数没有函数类型.

int sqlite3_bind_int(sqlite3_stmt*, int, int);

int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);

如果我无法以无符号方式存储它们,我肯定会有数字会溢出.

我自己需要自己管理吗?(即在插入数据库之前从db中选择或转换为signed类型后转换为无符号类型)

如果我自己必须自己管理,当比较真的意味着在无符号范围内时,如何做一些存储为有符号长整数的比较查询?

查看转换后的INTEGER数据类型,可以认为无符号长整数可以毫无问题地表示.

如果有其他可用解决方案,请赐教!谢谢!

Nic*_*las 9

SQLite数据库无法在其中存储无符号的64位整数.这只是数据的限制.

你的选择是:

  • 将其存储为字符串,根据需要进行转换.
  • 将其存储为二进制blob,根据需要进行转换.
  • 假设它是带有转换的带符号的64位整数,因此根据需要进行转换.
  • 将两条信息存储为两列:无符号的63位整数(低63位)和表示符号位的值.

由于这些是哈希值,您可能不关心除了相等测试之外的比较.因此,大多数这些方法对您来说都很合适.

  • @Michael:这是SQLite声明了一个无符号的64位类型。这并不意味着您可以将其存储在表中。[文档非常清楚](https://www.sqlite.org/datatype3.html),INTEGER值始终是有符号整数,最大为64位。 (3认同)
  • 但是这个页面(https://www.sqlite.org/c3ref/int64.html)明确提到了 `sqlite3_uint64` 类型,这是怎么回事?@! (2认同)

obm*_*arg 8

如果你想在sqlite数据库中存储uint64_t并仍然允许它在SQL中用作uint64_t,那么你可能需要编写一些自定义函数.

您只需要在发送到数据库或从数据库发送时将uint64_t转换为int64_t,然后编写自定义函数以执行您需要的任何比较等.例如,要做一个大于比较:

void greaterThan( sqlite3_context* ctx, sqlite3_value** values )
{
    uint64_t value1 = boost::numeric_cast< uint64_t >( sqlite3_value_int64( value[ 0 ] ) );
    uint64_t value2 = boost::numeric_cast< uint64_t >( sqlite3_value_int64( value[ 1 ] ) );
    sqlite3_result_int( ctx, value1 > value2 );
}

//Register this function using sqlite3_create_function
sqlite3_create_function( db, "UINT_GT", 2, SQLITE3_ANY, NULL, &greaterThan, NULL, NULL );
Run Code Online (Sandbox Code Playgroud)

然后在SQL中使用它:

SELECT something FROM aTable WHERE UINT_GT(value1,value2);
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要基于uint64_t的自定义归类,则应该能够以类似的方式使用sqlite3_create_collat​​ion.

它不是一个完美的解决方案,因为您需要为每个要执行的操作编写自定义函数,但它至少应该起作用.