火鸟 – 如何使用“(?为空)”来select空白参数

我正在使用链接到Firebird 2.0数据库的Excel报告,我有各种参数链接到对应于下拉列表的单元格引用。

如果一个参数留空,我想select所有可能的选项。 我试图通过把… WHERE …(?为null) ,如http://www.firebirdsql.org/refdocs/langrefupd25-sqlnull.html中所述 ,但我得到一个“无效的数据types“错误。

我find了一些关于这个错误的Firebird文档( http://www.firebirdfaq.org/faq92/ ),但是它声明: “解决方法是将值转换为适当的数据types,以便所有的查询返回相同的数据types为每列“。 我不太清楚在我的情况下这意味着什么。

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 

任何帮助是极大的赞赏。

如果你没有使用Firebird 2.5(但版本2.0或更高版本),或者如果你使用的驱动不支持Firebird 2.5中引入的SQL_NULL数据types,那么你需要使用明确的CAST ,例如:

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

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

现在,您引用的常见问题将提到将该值转换为适当的数据types ,这意味着您不应将其转换为可能导致转换错误的数据types(如果它不为null)。

在我的例子中,我转换为INTEGER ,但是如果这些值实际上是string,并且使用"IX0109302"作为值,那么将会得到一个转换错误,因为它不是合适的INTEGER 。 为了防止这种情况,您需要将其转换为足够长的(VAR)CHAR (否则会出现截断错误)。

如果您使用的是Firebird 1.5或更早的版本,这个技巧将无法使用,请参阅CORE-778 ,在这种情况下,您可能会TI.ITEM_NUMBER = ? OR 'T' = ? TI.ITEM_NUMBER = ? OR 'T' = ? ,在那里你设置第二个参数为'T' (真)或'F' (假)来表示你是否想要一切; 这意味着您需要将NULL检测移至您的调用代码。