如何解决SQLite没有绑定参数查询的结果,可与具有硬编码值的相同查询一起使用
我遇到了sqlite 3的一个奇怪问题。我有一个相对简单的查询,该查询在其WHERE
谓词中接受一个绑定参数。使用bound参数执行查询时,我得到0个结果,但是使用硬编码的值运行完全相同的查询,我得到了预期的结果数(> 0)。
我通过调用sqlite3_expanded_sql()
并检查生成的sql字符串,仔细检查了查询的准备情况。
我的查询带有绑定参数:
SELECT
b.name,Y(Transform(b.geom,4326)) "y",X(Transform(b.geom,4326)) "x"
FROM buildings b
WHERE Within(b.geom,Transform(polygonFromText(?,4326),27700)) > 0
我为绑定参数提供的值:
let rectWkt = """
polyGON((
-0.1381030196154711 51.51132617405723,-0.12929698038450965 51.51132617405723,-0.12929698038450965 51.50863378616471,-0.1381030196154711 51.50863378616471,-0.1381030196154711 51.51132617405723
))
"""
SELECT
b.name,Transform(polygonFromText('polyGON((
-0.1381030196154711 51.51132617405723,-0.1381030196154711 51.51132617405723
))',27700)) > 0
最后,这是sqlite3_expanded_sql()
的输出,在绑定上述值后调用该输出:
SELECT
b.name,27700)) > 0
除非我丢失了某些内容,否则它们是相同的语句,但是执行它们时会得到完全不同的结果。
我正在使用使用Swift绑定的sqlite c API执行查询,并且已经加载了Spatialite扩展(用于几何函数)。
我检查使用我的值对sqlite3_bind_text()
的呼叫是否为sqlITE_OK
。当我尝试遍历结果行时没有错误,我只是将sqlITE_DONE
作为第一个结果,即。结果集为空。
解决方法
我设法解决了这个问题:我需要将SQLITE_TRANSIENT
作为最后一个参数传递给我
呼叫sqlite3_bind_text
。我相信这是因为我呼吁执行
查询位于不同的范围内,到那时字符串值不在
范围。传递SQLITE_TRANSIENT
作为第五个arg指示Sqlite使其
自己的值副本。
特别是在Swift中,需要手动将其定义为
let SQLITE_TRANSIENT = unsafeBitCast(-1,to: sqlite3_destructor_type.self)
因为它是通过Sqlite头文件中的宏定义的(请参见:https://www.sqlite.org/c3ref/c_static.html)。
我之前绑定的电话是这样的:
guard
sqlite3_bind_text(stmnt,1,rectangleWKT,-1,nil) == SQLITE_OK
else {
throw DatabaseError.Bind(message: errorMessage)
}
但是应该更像是:
let SQLITE_TRANSIENT = unsafeBitCast(-1,to: sqlite3_destructor_type.self)
guard
sqlite3_bind_text(stmnt,SQLITE_TRANSIENT) == SQLITE_OK
else {
throw DatabaseError.Bind(message: errorMessage)
}
然后,我可以将准备好的语句传递给另一个函数来执行并获取结果:
return loadBuildings(forStatement: stmnt)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。