我使用[IBM][iSeries Access ODBC Driver][DB2 UDB]
版本V5R4
来查询链接的服务器。当我试图为现有(和工作)查询添加分页选项时,我收到此错误SQL0255 - Function not supported for query
。
我尝试添加分页之前正在运行的原始查询是:
select *
from openquery(MyLinkedServer,
'
select
ORG.FirstName as "First_Name",
ORG.LastName AS "Last_Name",
PRS.Address as Address
FROM Table1 AS ORG
inner join Table2 PRS
ON ORG.Id = PRS.Id
'
)
接下来我想添加分页,所以我修改了这样的代码:
select *
from openquery(MyLinkedServer,
'
select
ORG.FirstName as "First_Name",
ORG.LastName AS "Last_Name",
PRS.Address as Address
FROM
( SELECT R . * , ROW_NUMBER ( ) OVER ( ) AS ROW_NUM
FROM Table1 AS R) ORG
inner join Table2 PRS
ON ORG.Id = PRS.Id
WHERE ROW_NUM BETWEEN 1 AND 10
'
)
这是从标题中给出错误的实际查询。事实上,完整的错误是:
OLE DB provider "..." for linked server "MyLinkedServer" returned message "[IBM][iSeries Access ODBC Driver][DB2 UDB]SQL0255 - Function not supported for query.".
最后一部分。如果我删除了JOIN
并且只留下了这样的分页:
select *
from openquery(MyLinkedServer,
'
select
ORG.FirstName as "First_Name",
ORG.LastName AS "Last_Name",
PRS.Address as Address
FROM Table1 AS ORG
inner join Table2 PRS
ON ORG.Id = PRS.Id
'
)
接下来我想添加分页,所以我修改了这样的代码:
select *
from openquery(MyLinkedServer,
'
select
ORG.FirstName as "First_Name",
ORG.LastName AS "Last_Name"
FROM
( SELECT R . * , ROW_NUMBER ( ) OVER ( ) AS ROW_NUM
FROM Table1 AS R) ORG
WHERE ROW_NUM BETWEEN 1 AND 10
'
)
然后查询再次正常工作。因此,我能想到的唯一想法是,在此特定版本的同一查询中使用ROW_NUMBER()
和JOIN
时存在一些问题。
经过大量研究后,我唯一能发现的是每个版本都有我自己的特定版本,我发现了这个:
V5R4 supports OLAP. But there are some restrictions described in "SQL Reference".
An OLAP specification is not allowed if the query specifies:
- lateral correlation,
- a sort sequence,
- an operation that requires CCSID conversion,
- a UTF-8 or UTF-16 argument in a CHARACTER_LENGTH, POSITION, or SUBSTRING scalar function,
- a distributed table,
- a table with a read trigger, or
- a logical file built over multiple physical file members.
主要是获取数据,因此我需要保留JOIN
cluase,所以我的问题是如何为此DB2
特定版本的此查询添加分页?
答案 0 :(得分:3)
v5r4已经相当陈旧,大约在2007年,并且不再受IBM支持。
新信息
在v5r4,IBM仍在从原始经典查询引擎(CQE)转向新的SQL查询引擎(SQE)。为了使新的v5r4 OLAP功能起作用,查询必须由SQE处理。
但是,某些事情可能会迫使系统使用CQE。最有可能的。 - 仅存在选择/省略逻辑文件 - 在WHERE子句中使用诸如UPPER()之类的函数。
您可以通过在查询选项文件" QAQQINI"中设置IGNORE_DERIVED_INDEX = * YES来解决第一个问题。最佳做法是将其设置为本地副本,除非您想要影响系统上的每个查询。 在命令行上:
CRTDUPOBJ OBJ(QAQQINI)
FROMLIB(QSYS)
OBJTYPE(*FILE)
TOLIB(MYLIB)
DATA(*YES)
您可以将QAQQINI设置为在OLEDB驱动程序连接字符串(v5r3 +)上使用。但是看起来你正在使用ODBC。我不确定v5r4,但是7.1 ODBC驱动程序允许你指定"查询选项文件库"
不幸的是,第二个问题没有解决办法...... 如果偶然UPPER()或LOWER()是您正在使用的函数,可能是为了不区分大小写的处理;您可能能够创建不区分大小写的索引并将排序顺序更改为* LANGIDSHR。但是您提到文档指定如果您的查询指定了排序序列,OLAP函数将起作用。
结束新信息
我使用它已经有一段时间了。以下适用于7.1
with tbl as
(SELECT
ROW_NUMBER ( ) OVER ( ) AS ROW_NUM,
ORG.FirstName as "First_Name",
ORG.LastName AS "Last_Name",
PRS.Address as Address
FROM ORG
INNER JOIN PRS
ON ORG.ID = PRS.ID
)
SELECT *
FROM TBL
WHERE ROW_NUM BETWEEN 1 AND 10
请注意,如果未指定排序,您将获得未知的行集。
我建议您在行号
中添加一个窗口顺序子句with tbl as
(SELECT
ROW_NUMBER ( ) OVER (ORDER BY ORG.LASTNAME ) AS ROW_NUM,
ORG.FirstName as "First_Name",
ORG.LastName AS "Last_Name",
PRS.Address as Address
FROM ORG
INNER JOIN PRS
ON ORG.ID = PRS.ID
)
SELECT *
FROM TBL
WHERE ROW_NUM BETWEEN 1 AND 10
好的,显然上面的内容并不适用于5.4 ...尝试另一层CTE
with tbl as
(SELECT
ORG.FirstName as "First_Name",
ORG.LastName AS "Last_Name",
PRS.Address as Address
FROM ORG
INNER JOIN PRS
ON ORG.ID = PRS.ID
)
, tbl2 as
(SELECT
ROW_NUMBER ( ) OVER (ORDER BY "Last_Name" ) AS ROW_NUM,
, tbl.*
FROM TBL
)
SELECT *
FROM TBL2
WHERE ROW_NUM BETWEEN 1 AND 10
其他几种技术......
您可以将结果集加载到临时文件中,然后您就可以使用ROW_NUMBER()。
或者您可以考虑以下事项:
基本上,假设你想要每页10行,你想要第5页(即行41-50)。以下将给你。最初,表现并不是太糟糕。但每页都会变得更糟。您基本上希望用户不会在100次上下页。幸运的是,大多数人都没赢。
select *
from (select *
from (select * from mytbl
order by myfld
fetch first 50 rows only
) as t1
order by myfld desc
fetch first 10 rows only
) as t2