Db2

DB2 BOOLEAN 類型、EXISTS 謂詞和可空性奇怪行為

  • August 13, 2020

我正在使用 DB2 LUW v11.1.4.5,

似乎 EXISTS 謂詞,當 FALSE 返回 NULL 時(是否記錄在案?)在以下查詢X is nulltrue,所有其餘的行為就像FALSE是 的同義詞NULL,但元數據表明所有列都不可為空(請參閱dbfiddle

with boolstmt as
(
 select  'exists' stmt,
   exists(select 1 from sysibm.sysdummy1 where ibmreqd = 'N') as x
 from sysibm.sysdummy1
)
select
stmt,
x,
x is null "x is null",
not x "NOT x",
x = FALSE "x = FALSE",
smallint(x) "smallint(x)",
char(x) "char(x)"
from boolstmt

現在使用以下查詢,每列都可以為空,它表明x確實NULLEXISTS

with boolstmt as
(
 select  'exists' stmt,
   exists(select 1 from sysibm.sysdummy1 where ibmreqd = 'N') as x
 from sysibm.sysdummy1
 union all
 select  'count' stmt,
   (select count(*) from sysibm.sysdummy1 where ibmreqd = 'N') > 0 as x
 from sysibm.sysdummy1
)
select
stmt,
x,
x is null "x is null",
not x "NOT x",
x = FALSE "x = FALSE",
smallint(x) "smallint(x)",
char(x) "char(x)"
from boolstmt

我的問題是:有人知道嗎,在我看來這是伺服器上的問題,但您知道它是否來自 JDBC 驅動程序(使用 4.27.25)?使用更高版本的問題仍然存在嗎?

一個有趣的問題,答案並不那麼有趣:在這個簡單的例子中,你EXISTS被優化掉了,所以引用這個謂詞評估結果的嘗試是未定義的。如果您執行db2exfmt(或另一個可以檢索語句的“優化”版本的工具),您將看到這就是最終執行的內容:

SELECT 'exists' AS "STMT",
  $INTERNAL_FUNC$() AS "X",
  $INTERNAL_FUNC$() AS "x is null",
  $INTERNAL_FUNC$() AS "NOT x",
  $INTERNAL_FUNC$() AS "x = FALSE",
  SMALLINT($INTERNAL_FUNC$()) AS "smallint(x)",
  CHAR($INTERNAL_FUNC$()) AS "char(x)",
  $INTERNAL_FUNC$() AS "Y",
  $INTERNAL_FUNC$() AS "y is null",
  $INTERNAL_FUNC$() AS "NOT y",
  $INTERNAL_FUNC$() AS "y = FALSE",
  SMALLINT($INTERNAL_FUNC$()) AS "smallint(y)",
  CHAR($INTERNAL_FUNC$()) AS "char(y)" 
FROM (SELECT NULL 
FROM (VALUES ) AS Q1 
WHERE ('Y' = 'N')) AS Q2

這很可能是“按設計工作”™,因為謂詞(其中EXISTS之一)並不打算用來代替表達式。Db2 試圖盡最大努力謂詞評估結果轉化為值,但優化器佔了上風。

當您在它們各自所屬的地方使用表達式和謂詞時,事情會如您所願:

with boolstmt as
(
 select  'exists' stmt,
   case when exists(select 1 from sysibm.sysdummy1 where ibmreqd = 'N') then true else false end as x
 from sysibm.sysdummy1
)

引用自:https://dba.stackexchange.com/questions/273650