Oracle9i:过滤器表达式无法在运行时排除数据

Posted

技术标签:

【中文标题】Oracle9i:过滤器表达式无法在运行时排除数据【英文标题】:Oracle9i: Filter Expression Fails to Exclude Data at Runtime 【发布时间】:2009-01-27 15:51:21 【问题描述】:

我必须在一个 VB6 程序中维护一个相对简单的选择语句。 (抑制你天生的颤抖倾向;我继承了这个东西,不是我写的。)

陈述很简单(为了清晰起见重新格式化):

select distinct 
   b.ip_address 
from 
   code_table a, 
   location b 
where 
   a.code_item = b.which_id and 
   a.location_type_code = '15' and 
   a.code_status = 'R'

有问题的表返回数据库中的 IP 地址列表。有问题的关键列是code_status。前段时间,我们意识到其中一个 IP 地址不再有效,因此我们将其状态更改为 I(无效)以将其排除在查询结果中。

当您在 SQL Plus 或 SQL Developer 中执行上述查询时,一切正常。但是当你从 VB6 中执行它时,对code_status 的检查被忽略,并且无效的 IP 地址出现在结果集中。

我的第一个猜测是结果缓存在某个地方。但是,不是甲骨文专家,我不知道去哪里找。

这是古老的 VB6 代码。 SQL 嵌入在应用程序中。目前,我没有时间将其重写为存储过程。 (如果有机会,我会有一天。)但是,我需要知道是什么导致了这种行为差异以及如何消除它。如果它发生在这里,它很可能发生在其他地方。

如果有人能推荐一个好看的地方,我将非常感激。

【问题讨论】:

【参考方案1】:

一些随机的想法:

您确定您提交了使 IP 地址无效的更改吗?其他人(使用另一个数据库连接/用户)可以看到更改后的 code_status 吗?

你确定结果从数据库返回后没有修改吗?

您确定您在 SQLPlus 中使用的数据库连接与代码中的“相同”数据库连接(数据库、用户等)吗?

您确定这确实是发送到数据库的 SQL 吗? (您可以通过跟踪 Oracle 服务器或调试 VB 代码来检查)。重新格式化可能改变了“某些东西”。

在我的脑海中,我想不出任何可能“重新插入”不需要的 ip 的“缓存”。希望以上内容能给您一些关于在哪里查看的想法。

【讨论】:

在四个建议中,COMMIT 正在敲响警钟。我知道我在 SQL Developer 中执行了更新语句,之后我可以选择正确修改的结果集。但是从客户那里,不受欢迎的记录仍然出来。 (续) 也许我需要在执行更新后将更改提交到数据库。我没有使用事务或任何东西(这是 SQL Developer 中的一个简单的 UPDATE 语句),所以我认为没有必要,但我们知道,Oracle 一点也不像 SQL Server。 Oracle 中的一切都是事务,所以确实需要提交。通常,如果您从 SQL*Plus 或 SQL Developer 之类的东西中干净地退出,它将提交您的更改。 'Autocommit' 最好不要依赖...仔细检查当您打开一个新的 SQLDeveloper 时,您仍然可以看到您所做的更改。如果需要,请再次更新,然后提交。【参考方案2】:

除了 IronGoofy 提出的建议之外,您是否尝试过交换最后两个子句?

where
   a.code_item = b.wich_id and
   a.code_status = 'R' and
   a.location_type_code = '15'

如果您得到一组不同的结果,那么这可能表明正在进行某种争吵,导致实际上将狡猾的 SQL 发送到数据库。

【讨论】:

我试了一下你的答案,结果集没有区别。 :-/【参考方案3】:

存在导致错误答案的 Oracle 错误。这肯定不是那个时代之一。通常它们涉及视图和功能以及 dblink 和月相的一些奇怪组合......

它没有缓存在任何地方。 Oracle 直到 11 点才缓存结果,即便如此,它也知道在答案可能发生变化时更改缓存。

我猜这是一个数据问题。您在查询中的 IP 地址上有一个 DISTINCT,为什么?如果没有唯一性约束,您的 IP 地址可能有多个副本,而您只修复了其中一个。

而且您的 Code_status 与您的 IP 地址位于完全不同的表中。您在代码表中将状态设置为“I”,然后从 Location 表中获取 IP 列表。

停止思考斑马,开始思考马。这几乎可以肯定只是您不完全理解的数据。

运行这个

select 
   a.location_type_code, 
   a.code_status 
from 
   code_table a, 
   location b 
where 
   a.code_item = b.which_id and 
   b.ip_address = <the one you think you fixed>

我敢打赌,你会得到一个带有“I”的行和另一行带有“R”的行

【讨论】:

我认为如果这是一个数据问题,它会在服务器和客户端上产生相同的结果。 挠头我更倾向于认为这与我的连接、我正在使用的适配器或未能提交更改有关。 再说一次,我不是甲骨文专家,甲骨文似乎没完没了的反直觉设计决策让我感到惊讶。每次我发现他们吹嘘自己的“ANSI 合规性”时,我都会轻笑。 是的,结果不同。您是否运行了该查询?如果没有显示,我会查看驱动程序/客户端 - 升级。 只有当你已经有一种倾向于一个方向的直觉时,事情才会反直觉。你不是天生就有对 RDBMS 的直觉,它是发展起来的。我认为 MSSS 做出了许多同样违反直觉的决定。我希望他们能完全删除 ANSI 语法,我最讨厌什么了。【参考方案4】:

我建议您查看 V$SQL 系统视图,以确认您认为 VB6 代码正在运行的查询实际上就是它正在运行的查询。

类似的东西

select sql_text, fetches
where sql_text like '%ip_address%'

验证 SQL_TEXT 是否是您所期望的,并且在您执行代码时 FETCHES 计数会增加。

【讨论】:

以上是关于Oracle9i:过滤器表达式无法在运行时排除数据的主要内容,如果未能解决你的问题,请参考以下文章

bigQuery 和 GA-Premium 集成:从 GA 中的未过滤视图导出数据时,如何在 bigQuery 中使用 IP 过滤器(以排除内部流量)

根据多个筛选条件 - SQL访问排除记录

oracle9i的erp数据库无法正常关闭的解决方法。

运行时应用过滤器似乎无法正确过滤数据

Oracle9I不能登录控制台。用PLSQL登录数据库,提示ORA-1215,无法解析服务名——server_name.登录企业管理

怎么安装Oracle9i