Oracle WITH 子句不返回数据

Posted

技术标签:

【中文标题】Oracle WITH 子句不返回数据【英文标题】:Oracle WITH clause returns no data 【发布时间】:2011-09-21 20:54:28 【问题描述】:

我尝试在 Oracle 中使用 WITH 子句,但它没有返回任何数据。

这是我正在尝试运行的查询...

with test as 
 (select count(*)  
 from my_table)
select *
from test;

当我运行此代码时,我会返回 my_table 中的记录数

select count(*)  
 from my_table

我在 Oracle 10g 上,所以查询应该可以工作...

select * from v$version;

产量

Oracle 数据库 10g 企业版 10.2.0.4.0 - 64bi PL/SQL 版本 10.2.0.4.0 - 生产 CORE 10.2.0.4.0 生产 适用于 Solaris 的 TNS:版本 10.2.0.4.0 - 生产 NLSRTL 版本 10.2.0.4.0 - 生产

可能是权限问题还是什么?

*编辑:*

我相信我的问题很明确。使用 WITH 语句不会为我返回任何记录,即使 WITH 语句中的“select count(*) from my_table”语句工作正常,这会让我相信还有另一个我无法弄清楚的问题,因此这个问题:)

编辑 2

好的,所以如果我尝试从 SQL Server Management Studio 的链接服务器执行查询,我会得到一些错误信息:

sg 7357, Level 16, State 2, Line 1 无法处理对象“测试为 (选择计数(*) 来自 v$version) select * from test;"。链接服务器“MyServer”的 OLE DB 提供程序“MSDAORA”表明该对象没有列,或者当前用户对该对象没有权限。

【问题讨论】:

作为实验,将test这个词重命名为xyz123 请澄清您的问题。看起来 DCookie 在下面提供了工作示例。即使 my_table 的记录为零,您也应该得到一个 1 行 1 列的结果,显示为“0” 这听起来像是 PL/SQL Developer 做错了什么。当你从 SQL*Plus 运行它时,你得到相同的“结果”吗? 不,我在第二次编辑时收到了消息 SQL Server Management studio”是不是 SQLPlus。请尝试使用 SQLPlus。该消息似乎表明管理工作室无法正确使用该语句。 【参考方案1】:

也许优化器正在实现计数查询(愚蠢,我同意)。这是在黑暗中拍摄,但你有这些特权吗?

grant query rewrite to youruser; grant create materialized view to youruser;

【讨论】:

我不能授予任何特权,我什至不确定我可以查看我的特权到底是什么。我在一个伪 IT 部门工作,所以我公司的 DBA 不想帮助我。 这似乎是与物化视图相关的特权问题。【参考方案2】:

尝试给聚合一个别名。

with test as 
 (select count(*) as MyCount 
 from my_table)
select MyCount
from test;

【讨论】:

【参考方案3】:

以下对我来说效果很好 (10gR2)

SQL> with test as
  2   (select count(*)
  3   from user_tables)
  4  select *
  5  from test;

  COUNT(*)
----------
       593

SQL> 

你用的是什么客户端?

【讨论】:

我正在使用 PL/SQL Developer v 7.0.3.1123 我有 PL/SQL Developer v9.0.1,它在那里工作。您可以在 SQL*Plus 中尝试一下吗?【参考方案4】:

这个问题令人困惑。你是说你还是没有从my_table取回计数?

您应该返回计数,因为这正是您在 with 子句中要求的。

类似于写作:

选择 * from (select count(*) from my_table);

【讨论】:

【参考方案5】:

前几天我公司的一些人遇到了这个问题 - 我们将其追溯到 PL/SQL 开发人员正在使用的 Oracle 客户端版本 [因此是 OCI.dll] 版本 .我们的一些开发 PC 安装了 Oracle 8 (!) 客户端以及更新的版本。

症状是使用 WITH 子句编写的查询不仅没有返回任何行,而且也没有返回任何列!如果您手动设置应用程序以获取 Oracle 11 oci.dll,那么一切正常。

我认为发生的事情是 Oracle 8 早于 WITH 子句(在 Oracle 9 中引入,随后得到增强)。现在,大多数情况下,您可以让不同版本的 Oracle 客户端和服务器相互通信。然而,由于客户端具有一定的“智能”,它应该半知道它正在向数据库提交什么样的操作,SQL 的某种形式的原始解析也是如此。由于它不将命令识别为 SELECT,因此将其视为某些未知命令 [例如可能是 DDL 命令] 并且不将其识别为返回结果集。如果您为会话打开 SQL_TRACE,您可以看到 SQL 在服务器上被 PARSEd 和 EXECUTEd 正常执行,但没有调用 FETCH。

我最近在尝试使用 Oracle 12 中允许内联函数定义的新 WITH 语法时也遇到了类似的情况。如果您尝试使用基于 Oracle 11 胖客户端的应用程序(例如 PL/SQL developer 或 SQL*Plus)的简单示例,则会出现错误。如果您使用 Oracle 12 客户端或不依赖客户端安装的瘦客户端应用程序,那么它可以工作。

【讨论】:

以上是关于Oracle WITH 子句不返回数据的主要内容,如果未能解决你的问题,请参考以下文章

包含使用 with 子句的 sql 的 oracle 管道函数

Oracle Reports 中的从属 WITH 子句

EXISTS 不适用于 WITH 子句中的子查询

WITH 子句可以在不使用 Select 语句的情况下具有硬编码值吗?

返回导致错误:缺少表的 FROM 子句条目

在 Where 子句中选择不返回数据