Java 如何在SQL中从无别名的内联函数列标题中进行选择?
我正在编写一个Java程序,它从Oracle数据库中获取一个(SQL查询)字符串,对同一个数据库执行该字符串,然后执行另一个查询以获得所需的列映射,以便根据外部结果验证该数据 我想在一个SQL调用中完成这一切,这样我就可以使用PreparedStatement.executeQuery干净地返回Java ResultSet对象 到目前为止,我解决这个问题的方法是首先引用列映射查询,然后编写一个包装器,从存储的查询中获取必要的列。例如,结果SQL查询可能如下所示:Java 如何在SQL中从无别名的内联函数列标题中进行选择?,java,sql,oracle,Java,Sql,Oracle,我正在编写一个Java程序,它从Oracle数据库中获取一个(SQL查询)字符串,对同一个数据库执行该字符串,然后执行另一个查询以获得所需的列映射,以便根据外部结果验证该数据 我想在一个SQL调用中完成这一切,这样我就可以使用PreparedStatement.executeQuery干净地返回Java ResultSet对象 到目前为止,我解决这个问题的方法是首先引用列映射查询,然后编写一个包装器,从存储的查询中获取必要的列。例如,结果SQL查询可能如下所示: SELECT col1, col
SELECT col1, col2 FROM(
select col1, col2, col3 from table a
)
在上面的示例中,col3被丢弃,而无需编辑存储的SQL查询
这一直有效,直到我达到以下边缘情况-我的代码生成的SQL是:
SELECT NVL(RESTRICTTABLE.FIRSTRESTRICT,0), NVL(RESTRICTTABLE.LASTRESTRICT,0) FROM(
select a, NVL(RESTRICTTABLE.FIRSTRESTRICT,0), NVL(RESTRICTTABLE.LASTRESTRICT,0)
from (sometable and wheres)
)
就我所知,似乎没有一种方法可以引用该函数调用,而不在原始查询中使用别名,对吗?我无法在不写入临时表的情况下引用列号(并且我没有此应用程序的写入权限),也无法通过其功能签名直接引用列号
有什么简单的方法可以解决这个问题吗?使用
WITH
条款(11.2+):
更新
如果SELECT
语句已经以with
子句开头,则不能这样做,但可以“相当”简单地重新排列该语句,即找到实际的SELECT
语句,并将其移到新的with
元素中
例如:
-- Before
WITH A AS (
SELECT ... FROM tableA ...
), B AS (
SELECT ... FROM tableB ...
)
SELECT ... FROM A, B, tableC ...
-- After
WITH A AS (
SELECT ... FROM tableA ...
), B AS (
SELECT ... FROM tableB ...
), X (C1, C2, C3) AS (
SELECT ... FROM A, B, tableC ...
)
SELECT C2, C3
FROM X
您应该能够在外部查询中将列表达式括在双引号中,首先转换为大写。这项工作:
select "LOWER(DUMMY)"
from
(
select lower(dummy) from dual
)
LOWER(DUMMY)
------------
x
所以理论上你可以强迫你的陈述:
SELECT "NVL(RESTRICTTABLE.FIRSTRESTRICT,0)", "NVL(RESTRICTTABLE.LASTRESTRICT,0)" FROM(
select a, NVL(RESTRICTTABLE.FIRSTRESTRICT,0), NVL(RESTRICTTABLE.LASTRESTRICT,0)
from (sometable and wheres)
)
但是,您受到标识符的最大长度的限制,从12cR1到12cR1仅为30字节,从12cR2增加到128字节。截断标识符可能会起作用,但可能会出现冲突
您最好获取原始内部查询的名称,并从中决定要使用哪些列。这在一定程度上取决于列映射的工作方式以及查询实际返回的内容
(当然,您也可以坚持要求存储的查询将其所有列表达式都别名,这样您就可以只引用这些列表达式了,但这听起来好像不是一个选项。)我以前没有指定,但是有一个嵌套的。不幸的是,在我尝试这个答案之前,我并不认为它是相关的。@a_horse_,根据,subquery_factoring_子句不允许指定新的列别名,这是这里使用的功能,所以为了让这个答案起作用,您需要11.2或更高版本。这就是我最终使用的数据库设置,以便使用单独的查询存储和检索外部选择中使用的列,即从“内部”选择中获取c1、c3、c4。因此,在设置“外部”查询时,我首先检查是否需要为该列添加别名(即,该列是否可用或超过30个字符),然后用双引号将其括起来。谢谢你的帮助!
SELECT "NVL(RESTRICTTABLE.FIRSTRESTRICT,0)", "NVL(RESTRICTTABLE.LASTRESTRICT,0)" FROM(
select a, NVL(RESTRICTTABLE.FIRSTRESTRICT,0), NVL(RESTRICTTABLE.LASTRESTRICT,0)
from (sometable and wheres)
)