我正在使用 double secondsSinceEpoch = 1.511554592277516E9;
long longSeconds = (long) secondsSinceEpoch;
long micros = Math.round((secondsSinceEpoch - longSeconds) * 1_000_000);
Instant inst = Instant.ofEpochSecond(longSeconds).plus(micros , ChronoUnit.MICROS);
函数来执行查询。我知道,根据以下帖子,使用sqlite3_exec()
组合可以获得各种好处。
sqllite query with encrypted std::string (unrecognized token)
但是,在我的情况下,我已经有一个库,它与_prepare, _bind, _step, _finalize
紧密耦合,很难改变。即使是出于教育目的,我想知道,如何在sqlite3数据库中输入特殊标记。目前,我正在使用C ++以编程方式从文件中读取此语句,并使用sqlite3_exec()
目前,以下声明给出错误:
sqlite3_exec()
错误在此符号INSERT INTO Convey(username, data, id, type)
VALUES('12345', '^Z^Dfine* ^HºÉÙ<98>ö÷×^B2^@', 'abcd', 31);
处显示为^@
。当我拆除语句并检查每个字符的ascii时,它显示SQL error: unrecognized token:
代替0
。 ^@
的类型,data
或TEXT
并没有什么区别。
请注意,&#34;数据&#34;,我想在这里输入一个序列化形式的Google protobuf消息。
逃避此类&#34; nul&#34;的正确方法是什么?喜欢sqlite中的字符,当必须使用BLOB
?
[注意:1种方法是用一些预定义的模式替换0,这种模式不太可能在二进制字符串中找到,然后在读取时恢复它们。我也对这个解决方案持开放态度。]
答案 0 :(得分:0)
值为零的字符不是有效的UTF-8字符,因此无法直接在SQL中编写。
仅供记录:您应该使用参数。 但是如果你想在SQL中这样做,你必须写一个blob literal:
... VALUES('12345', x'1A0466696E652A2008BAC9D998F6F7D7023200', 'abcd', 31);
答案 1 :(得分:0)
似乎INSERT
具有blob性质的数据是不可能的,即包含NUL('\ 0')字符(或可能是新行'\ n'字符)。
因此,现在我按以下方式插入:
即。 '^Z^Dfine* ^HºÉÙ<98>ö÷×^B2^@'
看起来像'^Z^Dfine* ^HºÉÙ<98>ö÷×^B20#<position>'
在读取字符串时,必须对其进行解码。到目前为止,这非常有用且工作得很好!
对于有兴趣的人,这里是替换'\ 0'的代码:
#define SQLa_STRING_END '%'
#define SQLa_NUL_SEPARATOR ','
#define SQLa_NUL_TOKEN '0'
string
ToString (const string& s_, // need to enclose with '' and add ' before '
const bool isEncodingString = false)
{
string s = s_;
const char apostrophe = '\'';
bool isStringEndPending = isEncodingString;
for(size_t i = 0, length = s.length(); i < length; ++i)
switch(s[i])
{
case apostrophe:
s.insert(i++, 1, apostrophe);
++length;
break;
case 0:
if(isEncodingString)
{
if(isStringEndPending)
{
s += SQLa_STRING_END;
isStringEndPending = false;
}
s[i] = SQLa_NUL_TOKEN; ;
s += std::to_string(i) + SQLa_NUL_SEPARATOR;
}
default:
break;
}
s.insert(0, 1, '\'');
return s += '\'';
}
string
FromString (const char value[]) // enclosing '' are not present
{
string s = value;
if(const auto posEnd = s.rfind(SQLa_STRING_END) + 1)
{
std::replace(s.begin() + posEnd, s.end(), SQLa_NUL_SEPARATOR, '\0');
for(auto pos = posEnd, length = s.length() - 1;
pos < length;
s[::atoll(&s[pos])] = 0, pos = s.find(SQLa_NUL_SEPARATOR, pos) + 1);
s.erase(posEnd - 1);
}
return s;
}