4

我们将 Sybase ASE 用于我们从头开始开发的应用程序。我们有具有位列的表。在 Sybase 中,Bit 数据类型不能为空。这对于我们存储在表中的记录来说很好,但是我们的 SEARCH 存储过程存在设计问题。我们在很大程度上依赖于存储过程的代码生成器和相应的数据访问层类(在 .NET 中使用 Dapper)。由于我们无法将 Bit 参数的 NULL 传递给我们的 SEARCH 存储过程,因此我们只能将具有 1 或 0 值的记录检索到 Bit 列。下面的例子:

Table1
Column1 INT NULL,
Column2 BIT

SPROC1
@Column1 INT NULL,
@Column2 BIT

SELECT
Column1,
Column2
FROM
Table1
WHERE
Column1 = ISNULL(@Column1, Column1) AND
Column2 = ISNULL(@Column2, Column2) --since @Column2 contains either 1 or 0, this search sproc cannot return both

有一些解决方法,例如引入另一个 BIT 参数来表示是否跳过匹配位列,但是由于我们编写和维护存储过程代码生成器,我们希望使存储过程尽可能简单。更不用说这必须为每个位列/参数完成。另一种方法当然是将位数据类型更改为 tinyint。但这是一个有效/好的设计吗?对我来说似乎不是一个好习惯,但这应该可以解决我们所有的 Sybase 问题。我们可以创建一个自定义的 tinyint 数据类型,它可以为空并且应该只允许 0 和 1。如果我们更改为 tinyint,我们将别无选择,只能将数据访问类的布尔属性更改为 int16(我可以接受,只是解决位问题)。

有什么建议吗?

4

1 回答 1

0

基于上述生成器,传递 null 表示不基于该列进行过滤。如果您可以修改生成器代码,请检查以下解决方案:

在 Sybase 中,位数据类型接受除 0 和 1 以外的值,但总是被解释为 1。

存储过程可以通过传递 (-1) 或传递 (3) 来调用;当一个人的目标是不基于该列进行过滤时。并且可以更新生成器的代码以即时生成以下 sql:

SELECT
Column1,
Column2
FROM
Table1
WHERE
Column1 = ISNULL(@Column1, Column1) AND
( Column2 = ISNULL(@Column2, Column2) or ( @column2 not in (1,0) ) )
Column3 = ISNULL(@Column3, Column3) AND 
.....
于 2013-11-13T03:36:17.880 回答