疑難排解實務練習 9:為何 Content Manager OnDemand 不支援查詢結果修飾元 SQL 子句

症狀

數個指令和 API 容許使用者送出原始 SQL 用於查詢 OnDemand 應用程式群組資料表。然而,由於送出的 SQL 未經剖析或驗證,特定的查詢結果修飾元不受支援。這些查詢結果修飾元包括但不限於:
  • ORDER BY
  • READ ONLY
  • FETCH FIRST
  • OPTIMIZE FOR
  • SORT ASC/DESC
  • GROUP BY

原因

因為 Content Manager OnDemand 應用程式群組的整體設計而發生這種情況。OnDemand 使用資料庫區段、多個表格,甚至多個查詢,以增加查詢的效能並減輕資料庫的工作量。對照應用程式群組資料表的 SQL 查詢一開始僅限於符合資料庫區段限制的表格。針對每個資料表使用開始及停止日期,以達成上述目標。表格清單用來產生具有 UNION ALL SQL 陳述式的 full-select。這個產生的 SQL 字串受限於部分限制,例如所產生的 SQL 陳述式長度上限以及在單一查詢中搜尋的表格數目。這些產生的 SQL 陳述式建立了在多個 select 陳述式中重複的部分高度複式查詢,同時搜尋一個大型的資料範這些產生的 SQL 陳述式會在搜尋大範圍的資料時,建立在多個 select 陳述式中重複的部分高度複式查詢。新增搜尋結果修飾元,例如 ORDER BY,加重了資料庫上的工作量。

解決問題

為了減少用戶端工作,Content Manager OnDemand 資料夾定義支援排序、分組和限制列數等動作。這種方式讓資料庫不必執行需要大量時間來最佳化以及大量記憶體來執行的複式查詢修正。

以下是使用 arsdoc 指令的範例,您在此送出像 ACCTNO LIKE ‘1001% 的 SQL 查詢,並指定像 12/01/2004 to 12/31/2004 的區段日期至 OnDemand:
arsdoc query -u user -p whatever -f "Credit Card Statements" 
-i "ACCTNO LIKE "1001" -s "12/01/2004,12/31/2004"
Content Manager OnDemand 伺服器使用資料庫區段值來決定需要搜尋哪些表格。這可能只會產生一個要搜尋的表格,所產生的 SQL 看來如下:
SELECT * FROM root.BAA20 WHERE ACCTNO LIKE ‘1001
在此情況下,您可以將 ORDER BY 之類的修飾元附加到您所送出的 SQL。所產生的 SQL 就會附加到單一 SELECT/WHERE 陳述式的尾端。
在另一個範例中,將資料庫區段日期範圍延伸至 01/01/2004-12/31/2004
arsdoc query -u user -p whatever -f "Credit Card Statements"
 -i "ACCTNO LIKE ‘1001" -s "01/01/2003,12/31/2004"
被搜尋的表格數增加,可能是增加兩個表格,而且所產生的 SQL 看來如下:
SELECT * FROM BAA18 WHERE ACCTNO LIKE ‘1001 UNION ALL
SELECT root.BAA19.*, ‘BAA19' FROM root.BAA19 
WHERE ACCTNO LIKE ‘1001 UNION ALL
SELECT root.BAA20.*,'BAA20' 
FROM root.BAA20 
WHERE ACCTNO LIKE ‘1001
這個範例指出使用 ORDER BY 之類的修飾元無法直接附加到每一個 where 子句。它導致無效的 SQL 語法,因為它被併入作為每一個 where 子句的一部分。有效的 SQL 將它附加到整個完整 select 陳述式的尾端。由於 Content Manager OnDemand 未剖析已送出的查詢 SQL,它無法將 ORDER BY 修飾元附加到完整 select 陳述式的尾端。
為進一步說明此範例,請將資料庫區段範圍變更為 01/01/1990-12/31/2004
arsdoc query -u user -p whatever -f "Credit Card Statements" -i
 "ACCTNO LIKE ‘1001" -s  "01/01/1990,12/31/2004"
表格數可能會增加到一百或更多,所產生的 SQL 太長或是跨越太多表格。在此情況下,OnDemand 會產生多個 full-select 查詢以完成作業,而且無法在查詢上產生有效的 SQL,讓它針對整個結果集執行 ORDER BY

在此情況下,Content Manager OnDemand 仰賴用戶端修改結果。使用 API 或 ARSDOC 之類的指令將 SQL 查詢直接送出到 Content Manager OnDemand,但只使用被查詢的欄位,並且一律提供一個區段日期範圍。若未提供區段日期範圍,應用程式群組中的所有表格都會被搜尋。在結果傳回之後,您可以照著修改它們。