I would like to know what the reasoning could be for inconsistent way sql server handles type overflowing. And what would be the proper way to prevent the silent data corruption SQL Server inflicts on us.
The well behaved int
An int for example gives a proper overflow exception
declare @b int = 123456789000
Msg 8115, Level 16, State 2, Line 3 Arithmetic overflow error converting expression to data type int.
The Silent bit
A bit value will be zero for zero and one for everything else you try to put in (with a little extra fun on an empty string).
declare @a bit = 123
, @b bit = ''
select a = @a, b = @b
output:
a b ----- ----- 1 0
create table #bit_type(a bit)
insert into #bit_type values (123), ('')
select * from #bit_type
output:
a - 1 0
declare @bit_type table (a bit)
insert into @bit_type values (123), ('')
select * from @bit_type
output:
a - 1 0
This behavior is often the cause of very hard to debug ETL problems (invalid value in an input file is silently converted to a 1 or a zero)
The schizophrenic varchar
Varchar (and char/nchar/nvarchar) is another highly annoying datatype
declare @c varchar(5)
select @c = '123456789'
print @c
The result is silently truncated.
12345
create table #varchar_type(a varchar(5))
insert into #varchar_type values ('123456789')
Here we get a proper overflow error.
Msg 8152, Level 16, State 14, Line 1
String or binary data would be truncated.
The statement has been terminated.
declare @varchar_type table(a varchar(5))
insert into @varchar_type values ('123456789')
Here we get a proper overflow error as well.
Msg 8152, Level 16, State 14, Line 2
String or binary data would be truncated.
The statement has been terminated.
BITSQL is assuming that ANY numeric value is
'TRUE', while an empty string or 0 is'FALSE'.The best way to handle this is through filtering in your code, i.e.:
VarcharSQL doesn’t consider
@variablesas mission-critical as tables. The overflow error on tables can be disabled as well by using theSET ANSI WARNINGS OFFcommand.I think the designers also assumed that if you are declaring a variable with a length, you will handle checking the length of that variable yourself. Other reasons could include:
This is different for a string than an int since a string can still be useful when truncated, while truncation fundamentally changes the nature and value of a number.
The recommended procedure is similar to that for bit: