Sql server SQL Server:如何在插入/更新时自动调整列的超出范围值?

Sql server SQL Server:如何在插入/更新时自动调整列的超出范围值?,sql-server,sql-update,sql-insert,outofrangeexception,Sql Server,Sql Update,Sql Insert,Outofrangeexception,我正在Windows 7上使用MS-SQL Server 2014。 在数据库中,我当前有一个名为“STATUS”的表,其中列的定义如下: DeviceSerial smallint 此表中有/将有超过6k条记录。 不幸的是,一些设备使用错误的序列号进行编程,例如43776而不是4376(技术人员键入了两次7…)。通常,设备序列值应在1-9999范围内。 显然,43776是smallint的超出范围的值,因此插入/更新操作崩溃:( 那么,问题是:在这种情况下,是否有办法让sql serve

我正在Windows 7上使用MS-SQL Server 2014。
在数据库中,我当前有一个名为“STATUS”的表,其中列的定义如下:

DeviceSerial   smallint
此表中有/将有超过6k条记录。
不幸的是,一些设备使用错误的序列号进行编程,例如43776而不是4376(技术人员键入了两次7…)。通常,设备序列值应在1-9999范围内。
显然,43776是smallint的超出范围的值,因此插入/更新操作崩溃:(


那么,问题是:在这种情况下,是否有办法让sql server检查插入/更新的值,如果DeviceSerial值大于9999,则为其输入0?(0表示未设置序列号或其他内容).

您可以在表中使用CONTAINT,这样,如果有人试图更新或插入超出范围的值,您将收到错误。这将使您的数据库保留rigth数据,并且不会在以后使用没有序列的设备时出现问题

ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
   DeviceSerial   >= 1 AND DeviceSerial   <= 9999--Inclusive
)

如果您有SQL Server 2012+,则可以使用TRYPARSE或TRYCONVERT

如果TRYPARSE无法将输入的值转换为请求的数据类型,它将返回NULL,可以合并为零

因此,如果您试图将
@MyVariable
插入到smallint中,可以将其放入insert语句中:

COALESCE(TRYPARSE(@MyVariable AS smallint),0)
插入不会出错,如果无法将值插入到smallint列中,则将插入零

如果您不仅要强制某个值在smallint范围内,而且要强制该值在1-9999的特定范围内,则可以使用大小写表达式:

CASE WHEN @MyVariable BETWEEN 1 AND 9999 THEN @MyVariable ELSE 0 END

这是一个超级解决方案:

ALTER TABLE dbo.Status ALTER COLUMN DeviceSerial int NOT NULL
不引发异常,允许您随时修复数字,并且您不必使用instead of触发器编程任何伪视图,也不必使用从客户端重写调用的存储过程编程任何伪视图


这是一种罕见的情况,我建议使用字符串而不是数字值。序列号通常意味着一组唯一的字符,可能是数字和字母。通常它可能有前导零,这对数字值没有任何意义,但却是唯一字符串的常规和持久部分。

d您的想法。约束检查将避免提示的InsertionTank,但我确实需要进行插入:这将是一个很好的反馈,让我看到所有设备都已正确设置,等等。您看到:0表示设备不正常(不可用),等等。在插入之前,在应用程序中更正它。让数据库强制执行约束。1)客户端2)存储过程3)而不是trigger@IvanStarostin:不是1。但如果可以的话,请详细说明第2条和第3条(作为常规答案)。我是sql初学者…我认为最好不要在数据库中插入不一致的数据,这就是我的建议。谢谢你的建议。然而,最好有某种自动更正。。。我知道不可能有一个真正的自动更正,但至少我希望有一个0(零)来代替:),原因如上所述。@groenhen,虽然你可以使用触发器“自动更正”坏数据,但我认为最好是验证和拒绝坏数据,而不是默默地修复它。@DanGuzman:触发器很好。更好的是,如果你可以添加一个解释作为常规答案:)我一定会感兴趣,并感谢:)Thx提前!呵呵,这就是我现在的“修复”(
int
type)…)我相信这是正确的(不管关于字符串的推理如何)。
ALTER TABLE dbo.Status ALTER COLUMN DeviceSerial int NOT NULL