使用SQLite ADO.Net Provider需要将GUID直接放入Query's Where子句中,而不使
本文关键字:Where 子句 Query Provider Net ADO SQLite GUID 使用 | 更新日期: 2023-09-27 18:10:32
是否有GUID是SQL查询本身的一部分,而不使用参数?
让我解释一下我到底想做什么以及为什么。我正在使用ADO的现有应用程序。Net创建并连接到SQLite数据库。当前数据库的结构和查询方法非常糟糕。我正在重新设计它的基本工作原理。然而,这不是一件可以很快完成的事情。当重新设计完成的时候,我有一个情况需要一个权宜之计。作为提示,代码最初实现背后的原因是模糊的,似乎是由一个几乎没有数据库知识的人构建的。重构整个数据库以不需要这种情况是最终的解决方案,但现在我只是希望在现有结构内工作。
数据库的设计依赖于GUID来唯一地标识行。为了执行过滤后的数据检索,系统动态地构建一个命令,该命令具有一个IN子句,列出应该检索的guid。现在,通过使用GUID类型的参数将GUID插入到查询中,因此查询将看起来像
SELECT * FROM data_table WHERE guid_col IN( ?, ?, ?, ?)
当我需要检索相对大量的信息时,问题就出现了。SQLite在单个查询中有1000个参数的限制。如果我需要为检索传递超过1000个guid,查询就会中断。在构建上述字符串时,它循环遍历GUID列表以插入问号并创建参数。我对这个问题的权宜之计是将GUID值直接插入到问号当前所在的位置,并放弃在查询中使用参数。毕竟,这是一种将参数用于不需要使用参数的目的。
这个"解决方案"的问题是,我似乎无法获得GUID来匹配列中的数据,即查询总是返回null。我知道guid不是SQLite的原生类型,它实际上被表示为BLOB(是的,我确信我们正在使用BLOB而不是字符串表示)。然而,我一直无法使查询正确执行。
到目前为止,我已经尝试了以下所有方法:
我已经尝试在GUID上调用ToString(),因此查询看起来像
SELECT * FROM data_table WHERE guid_col IN
( 'b5080d4e-37c3-4286-9c3a-413e8c367f36', 'aa0ff789-3ce9-4552-9840-5ed4d73c1e2c')
我尝试在GUID上调用ToString("N"),因此查询看起来像
SELECT * FROM data_table WHERE guid_col IN
( 'b5080d4e37c342869c3a413e8c367f36', 'aa0ff7893ce9455298405ed4d73c1e2c')
我已经尝试在GUID上调用ToString("B"),因此查询看起来像
SELECT * FROM data_table WHERE guid_col IN
( '{b5080d4e-37c3-4286-9c3a-413e8c367f36}',
'{aa0ff789-3ce9-4552-9840-5ed4d73c1e2c}')
我已经尝试在GUID上调用ToByteArray(),并通过将每个字节添加到每个字节上调用ToString("X")的字符串中,将结果放入查询中,因此查询看起来像
SELECT * FROM data_table WHERE guid_col IN('4ED8B5C33786429C3A413E8C367F36', '89F7FAAE93C524598405ED4D73C1E2C')
在阅读SQLite文档时,我读到下面的"BLOB字面值是包含十六进制数据的字符串字面值,前面有一个"x"或";X"的性格。如果我试着把这个应用到我的查询中让它看起来像
SELECT * FROM data_table WHERE guid_col IN
( x'4ED8B5C33786429C3A413E8C367F36', x'89F7FAAE93C524598405ED4D73C1E2C')
我得到一个错误,说"x"不是可识别的符号。
是否有可能在不使用参数的情况下获得GUID到查询字符串中?
我建议您使用临时表来处理这样的事情。例如…
PRAGMA temp_store = MEMORY;
CREATE TEMP TABLE tbl_guids (guid_col text);
INSERT INTO tbl_guids VALUES ('b5080d4e-37c3-4286-9c3a-413e8c367f36');
INSERT INTO tbl_guids VALUES ('aa0ff789-3ce9-4552-9840-5ed4d73c1e2c');
... more inserts ...
SELECT * FROM data_table WHERE guid_col IN ( SELECT guid_col FROM tbl_guids);
DROP TABLE tbl_guids;
确保在所有INSERT INTO
语句周围包装一个事务。这将极大地提高性能。此外,通过设置PRAGMA temp_store = MEMORY
如果您有多个用户同时访问表,共享相同的连接,您将需要为临时表创建一些唯一性,例如在表名(如tbl_guids_9087
)中添加随机数。
如果在连接字符串中设置"BinaryGuid=False",则可以将GUID作为字符串传入。如果这样做了,"ToString()"应该可以正常工作。