我正尝试在vba中进行域查找,如下所示:
DLookup("island", "villages", "village = '" & txtVillage & "'")
这很好用,直到txtVillage类似于Dillon‘This,当撇号被当作单引号时,我得到一个运行时错误。
我已经编写了一个简单的函数来转义单引号-它将"'“替换为"''”。这似乎是经常出现的东西,但我找不到任何对做同样事情的内置函数的引用。我错过了什么吗?
发布于 2008-10-14 03:21:28
"Replace“函数应该可以做到这一点。根据上面的代码:
DLookup("island", "villages", "village = '" & Replace(txtVillage, "'", "''") & "'")
发布于 2008-10-14 03:14:19
比你想的还糟。想一想,如果有人像这样输入一个值,而您没有逃脱任何东西,会发生什么:
'); DROP TABLE [YourTable]
不是很漂亮。
没有内置函数来简单地转义撇号的原因是因为正确的处理方法是使用查询参数。对于Ole/Access样式的查询,您可以将以下内容设置为查询字符串:
DLookup("island", "village", "village = ? ")
然后分别设置参数。不过,我不知道如何从vba中设置参数值。
发布于 2008-10-14 08:04:09
尽管像DLookup这样的简写域函数很诱人,但它们也有其缺点。等效的Jet SQL类似于
SELECT FIRST(island)
FROM villages
WHERE village = ?;
如果你有多个匹配的候选者,它将选择“第一个”,“第一个”的定义取决于Jet/ACE引擎IIRC的实现(SQL引擎)和未定义。你知道谁会是第一个吗?如果你不这样做,那就避开DLookup :)
值得注意的是,Jet/ACE的答案要么是基于上次压缩数据库文件时的clusterd索引的最小值,要么是第一个(有效时间)插入值(如果数据库从未压缩过)。聚集索引依次由主键决定,如果存在唯一约束或定义在非空列上的索引,否则第一个(有效时间)插入的行。如果在NOT NULL列上定义了多个唯一约束或索引,那么哪个约束或索引将用于集群?我不知道!我相信你知道“第一”是不容易确定的,即使你知道怎么做!
我还看到了Microsoft从优化的角度避免使用域聚合函数的建议:
有关Access数据库http://support.microsoft.com/kb/209126中查询性能的信息
避免使用域聚合函数,如DLookup函数... Jet数据库引擎无法优化使用域聚合函数的查询
如果选择使用查询重写,则可以利用PARAMETERS语法,或者您可能更喜欢Jet 4.0/ACE过程语法,例如
CREATE PROCEDURE GetUniqueIslandName
(
:village_name VARCHAR(60)
)
AS
SELECT V1.island_name
FROM Villages AS V1
WHERE V1.village_name = :village_name
AND EXISTS
(
SELECT V2.village_name
FROM Villages AS V2
WHERE V2.village_name = V1.village_name
GROUP
BY V2.village_name
HAVING COUNT(*) = 1
);
这样,您就可以使用引擎自己的功能--或者至少是它的数据提供程序的功能--根据需要转义所有字符(而不仅仅是双引号和单引号)。
https://stackoverflow.com/questions/199889
复制相似问题