簡體   English   中英

DB2 SQL0255-嘗試使用JOIN用戶ROW_NUMBER時不支持查詢功能

[英]DB2 SQL0255 - Function not supported for query when try to user ROW_NUMBER with JOIN

我正在使用[IBM][iSeries Access ODBC Driver][DB2 UDB]版本V5R4來查詢鏈接服務器。 我收到此錯誤SQL0255 - Function not supported for query嘗試向現有(且正在運行)的查詢添加分頁選項時SQL0255 - Function not supported for querySQL0255 - 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線索,所以我的問題是如何針對該特定版本的DB2向該查詢添加分頁?

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM