1

I am working with an Excel Report linked to a Firebird 2.0 DB and I have various parameters linked to cell references that correspond to drop down lists.

If a parameter is left blank, I want to select all the possible options. I am trying to accomplish this by putting ... WHERE... (? is null), as described in http://www.firebirdsql.org/refdocs/langrefupd25-sqlnull.html , but I get an "Invalid Data Type" error.

I found some Firebird documentation (http://www.firebirdfaq.org/faq92/) where it talks about this error, but it states that "The solution is to cast the value to appropriate datatype, so that all queries return the same datatype for each column." and I'm not quite sure what that means in my situation.

SELECT C.COSTS_ID,
       C.AREA_ID,
       S.SUB_NUMBER,
       S.SUB_NAME,
       TP.PHASE_CODE,
       TP.PHASE_DESC,
       TI.ITEM_NUMBER,
       TI.ITEM_DESC,
       TI.ORDER_UNIT,
       C.UNIT_COST,
       TI.TLPE_ITEMS_ID
FROM TLPE_ITEMS TI
  INNER JOIN TLPE_PHASES TP ON TI.TLPE_PHASES_ID = TP.TLPE_PHASES_ID
  LEFT OUTER JOIN COSTS C ON C.TLPE_ITEMS_ID = TI.TLPE_ITEMS_ID
  LEFT OUTER JOIN AREA A ON C.AREA_ID = A.AREA_ID
  LEFT OUTER JOIN SUPPLIER S ON C.SUB_NUMBER = S.SUB_NUMBER
WHERE ((C.AREA_ID = 1 OR C.AREA_ID = ?) OR **(? IS NULL))**
  AND ((S.SUB_NUMBER = ?) OR **(? IS NULL))**
  AND ((TI.ITEM_NUMBER = ?) OR **(? IS NULL))**
  AND ((TP.PHASE_CODE STARTING WITH ?) OR **(? IS NULL))**
ORDER BY TP.PHASE_CODE

Any help is greatly appreciated.

4

1 回答 1

0

如果您使用的不是 Firebird 2.5(但版本 2.0 或更高版本),或者您使用的驱动程序不支持SQL_NULLFirebird 2.5 中引入的数据类型,那么您需要使用显式CAST,例如;

SELECT *
FROM TLPE_ITEMS TI
WHERE TI.ITEM_NUMBER = ? OR CAST(? AS INTEGER) IS NULL

这会将第二个参数标识为INTEGER驱动程序(和 Firebird),允许您将其设置为NULL.

现在您引用的常见问题解答提到将值转换为适当的 datatype,它们的意思是您不应该转换为如果它不为空则可能导致转换错误的数据类型。

在我的示例中,我强制转换为INTEGER,但如果值实际上是字符串并且您使用 say"IX0109302"作为值,您将收到转换错误,因为它不合适INTEGER。为防止这种情况,您需要转换(VAR)CHAR为足够长的长度(否则会出现截断错误)。

如果您使用的是 Firebird 1.5 或更早版本,则此技巧将不起作用,请参阅CORE-778,在这种情况下,您可能会逃脱类似的事情TI.ITEM_NUMBER = ? OR 'T' = ?,您将第二个参数设置为'T'(true) 或'F'(false) 以表明您是否想要一切与否;这意味着您需要将 NULL 检测移至调用代码。

于 2013-06-05T16:10:58.127 回答