我必须使用基于 SQL Anywhere 5 的遗留系统,数据库访问层使用嵌入式 SQL 在 C++ 中。我遇到的问题并不是真正的 C++ 问题,而是嵌入式 SQL 迫使我们使用无法动态生成的 SQL 语句。有许多表包含许多具有 datatype 的列double
。尽管主应用程序期望这些列不是NULL
,但大多数列都没有NOT NULL
约束。ISNULL
为了避免应用程序崩溃,我们在 SQL 中使用了很多。例如,不仅仅是写
SELECT d1,d2,d3,d4 FROM table1;
我们写
SELECT ISNULL(d1,0),ISNULL(d2,0),ISNULL(d3,0),ISNULL(d4,0) FROM table1;
到目前为止,问题解决了,一切似乎都很好——我们想。现在,我们发现,例如,当d1
一行中包含 1.2345678987654321 时,则
SELECT d1 ...
结果是
1.2345678987654321
但
SELECT ISNULL(d1,0) ...
结果是
1.234567
其原因似乎是当您使用 double 和 0 之类的数字调用 ISNULL 时,会发生 ISNULL 的两个参数到NUMBER(30,6)
first 的某种类型转换,因此 d1 被削减为 6 位小数。简单的修复在这里
SELECT ISNULL(d1,CAST(0 AS DOUBLE)) ...
这将1.2345678987654321
再次给出预期,但会导致非常冗长的 SQL 语句:
SELECT ISNULL(d1,CAST(0 AS DOUBLE)),ISNULL(d2,CAST(0 AS DOUBLE)),ISNULL(d3,CAST(0 AS DOUBLE)), ISNULL(d4,CAST(0 AS DOUBLE))
所以我们试图找到一种更短的方法来在 SQL 中直接写一个双零:
SELECT ISNULL(d1,0e0)...
或者SELECT ISNULL(d1,0.0)...
不起作用,再次给出 1.234567。
SELECT ISNULL(d1,SIN(0))...
或者SELECT ISNULL(d1,1e-307)...
两者都有效,产生正确的 1.2345678987654321,但看起来都非常难看,只是写一个 0。
所以这里有一个问题:关于如何写这个更短/更易读/完全避免这个问题的任何想法?请记住,在我们的约束下,生成 SQL 语句都不是一个选项,更改数据库模式也不是。