使用SQLite ADO.NET提供程序需要将GUID直接放入查询的WHERE子句中,而不使用参数

niwlg2el  于 2022-11-14  发布在  SQLite
关注(0)|答案(2)|浏览(184)

有没有办法让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_COOL IN(‘4ED8B5C33786429C3A413E8C367F36’,‘89F7FAAE93C524598405ED4D73C1E2C’)
在阅读SQLite文档时,我读到了以下内容:“BLOB文字是包含十六进制数据的字符串文字,前面有一个”x“或”X“字符。

SELECT * FROM data_table WHERE guid_col IN
    ( x'4ED8B5C33786429C3A413E8C367F36', x'89F7FAAE93C524598405ED4D73C1E2C')

我收到一个错误,说“x”不是可识别的符号。
是否可以在不使用参数的情况下将GUID放入查询字符串中?

vof42yt1

vof42yt11#

我建议您用一张临时table来摆放这样的东西。比如..。

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;

确保将事务 Package 在所有INSERT INTO语句周围。这将大大提高性能。此外,通过设置PRAGMA temp_store = MEMORY,SQLite允许临时表完全存在于内存中
如果有多个用户同时访问共享同一连接的表,则需要使用临时表创建一些唯一性,例如向表名添加一个随机数,如tbl_guids_9087

nhhxz33t

nhhxz33t2#

如果在连接字符串中设置了“BinaryGuid=False”,则可以将GUID作为字符串传入。如果这样做了,“ToString()”应该可以很好地工作。

相关问题