Sql server SQL Server的不一致数据类型溢出处理是否有原因
我想知道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/
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>作为任务关键的表。表上的溢出错误也可以被禁用
我认为设计者还假设,如果您要声明一个长度为的变量,您将自己检查该变量的长度。其他原因可能包括:- 您正在设置变量的长度(大多数情况下不是自动设置的)
- 您正在指定输入
- 因此,您应该知道您的输入是否可能溢出,并在必要时进行检查
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