Sql server SQL Server的不一致数据类型溢出处理是否有原因

Sql server SQL Server的不一致数据类型溢出处理是否有原因,sql-server,sqldatatypes,Sql Server,Sqldatatypes,我想知道sql server处理类型溢出的方式不一致的原因是什么。怎样才能防止SQL Server对我们造成的无声数据破坏呢 行为良好的int 例如,int给出了一个适当的溢出异常 declare @b int = 123456789000 静音位 一个比特值将是零表示零,一表示您尝试输入的所有内容(在空字符串上有一点额外的乐趣) 输出: 输出: 输出: 这种行为通常是很难调试ETL问题的原因(输入文件中的无效值被静默转换为1或零) 精神分裂症患者varchar Varchar(和char/

我想知道sql server处理类型溢出的方式不一致的原因是什么。怎样才能防止SQL Server对我们造成的无声数据破坏呢

行为良好的
int
例如,int给出了一个适当的溢出异常

declare @b int = 123456789000
静音
一个比特值将是零表示零,一表示您尝试输入的所有内容(在空字符串上有一点额外的乐趣)

输出:

输出:

输出:

这种行为通常是很难调试ETL问题的原因(输入文件中的无效值被静默转换为1或零)

精神分裂症患者
varchar
Varchar(和
char
//
nvarchar
)是另一种非常烦人的数据类型

declare @c varchar(5)
select @c = '123456789'
print @c 
结果被自动截断

12345

这里我们得到了一个正确的溢出错误

Msg 8152,第16级,第14状态,第1行 字符串或二进制数据将被截断。 声明已终止

这里我们也得到了一个正确的溢出错误

Msg 8152,第16级,第14状态,第2行 字符串或二进制数据将被截断。 声明已终止

SQL假定任何数值为
'TRUE'
,而空字符串或0为
'FALSE'

处理此问题的最佳方法是在代码中进行过滤,即:

DECLARE @b BIT
DECLARE @v char(4) = '1234'

SET @b = (CASE WHEN @v = '1' THEN 1 ELSE 0 END)

SELECT @b
Varchar

SQL没有考虑<代码>变量> /Case>作为任务关键的表。表上的溢出错误也可以被禁用

我认为设计者还假设,如果您要声明一个长度为的变量,您将自己检查该变量的长度。其他原因可能包括:

  • 您正在设置变量的长度(大多数情况下不是自动设置的)
  • 您正在指定输入
  • 因此,您应该知道您的输入是否可能溢出,并在必要时进行检查
这与int不同,因为字符串在截断时仍然有用,而截断从根本上改变了数字的性质和值。

建议的程序与bit类似:

DECLARE @v varchar(10)
DECLARE @str varchar(25) = 'This is a longer string'

IF LEN(@str) <= 10
    SET @v = @Str
ELSE RAISERROR('Invalid string length!', 0, 1) WITH NOWAIT
DECLARE@v varchar(10)
声明@str varchar(25)=“这是一个较长的字符串”

对于任何数值,如果LEN(@str)位为真。我仍然认为这是一个很糟糕的设计决策,很容易出错。例如,BCP也会悄悄地将数据泵入位列。关于
SET ANSI WARNINGS OFF
的一点很好,我只希望变量也遵循此设置。例如,在动态sql中连接字符串时,varchar变量尤其棘手。(我知道,
varchar(max)
)@Filip-
bit
也会响应字符串
TRUE
FALSE
@Filip-更需要验证您的输入。我现在对所有位列设置检查约束。我感觉到了您的痛苦。四舍五入也不一致——有些类型向上取整,有些向下取整。小心。
create table #bit_type(a bit) 
insert into #bit_type values (123), ('')
select * from #bit_type
a
-
1
0
declare @bit_type table (a bit)
insert into @bit_type values (123), ('')
select * from @bit_type
a
-
1
0
declare @c varchar(5)
select @c = '123456789'
print @c 
create table #varchar_type(a varchar(5)) 
insert into #varchar_type values ('123456789')
declare @varchar_type  table(a varchar(5)) 
insert into @varchar_type values ('123456789')
DECLARE @b BIT
DECLARE @v char(4) = '1234'

SET @b = (CASE WHEN @v = '1' THEN 1 ELSE 0 END)

SELECT @b
DECLARE @v varchar(10)
DECLARE @str varchar(25) = 'This is a longer string'

IF LEN(@str) <= 10
    SET @v = @Str
ELSE RAISERROR('Invalid string length!', 0, 1) WITH NOWAIT