2

我必须使用基于 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 语句都不是一个选项,更改数据库模式也不是。

4

1 回答 1

2

不确定它是否适用于 v5 尝试设置数据库选项以通过 sql 将浮点数视为双精度数
运行查询

set option FLOAT_AS_DOUBLE = 'ON'

如果您希望它仅用于当前连接,请使用

set TEMPORARY option FLOAT_AS_DOUBLE = 'ON'

然后您可以尝试使用您的查询的第一个版本

于 2010-01-06T15:23:03.410 回答