SQL服务器:如何在insert/update时自动调整列的超出范围的值?
SQL Server: How to automatically adjust an out-of-range value for a column when insert/update?
我在 Windows 7.
上使用 MS-SQL Server 2014
在数据库中,我目前有一个名为 "STATUS" 的 table,其中一列的定义如下:
DeviceSerial smallint
这个table中有are/will条记录超过6k条。
不幸的是,有些设备使用错误的序列号进行编程,例如 43776 而不是 4376(技术人员输入了两次 7...)。通常,DeviceSerial 值应在范围内:1 - 9999.
显然,43776 是 smallint 的超出范围的值,因此 insert/update 操作崩溃:(
嗯,问题是:在这种情况下,有没有办法让 sql 服务器检查 inserted/updated 值,如果 DeviceSerial 值大于9999,填0? (0 表示未设置序列号或其他内容)。
您可以在 table 中使用约束,这样,如果有人尝试更新或插入超出范围的值,您就会收到错误消息。它会用正确的数据维护你的数据库,并且以后没有序列号的设备不会有问题。
ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
DeviceSerial >= 1 AND DeviceSerial <= 9999--Inclusive
)
或
ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
DeviceSerial BETWEEN 1 AND 9999
)
如果您有 SQL Server 2012+,您可以使用 TRYPARSE 或 TRYCONVERT。
如果 TRYPARSE 无法将输入的值转换为请求的数据类型,则它 returns NULL,可以合并为零。
因此,如果您尝试将 @MyVariable
插入到 smallint 中,您可以将其放入插入语句中:
COALESCE(TRYPARSE(@MyVariable AS smallint),0)
插入不会出错,如果无法将值插入到 smallint 列,则会插入一个零。
如果您不仅要强制一个值在 smallint 范围内,而且要在特定范围 1-9999 内,您可以使用 CASE 表达式来实现:
CASE WHEN @MyVariable BETWEEN 1 AND 9999 THEN @MyVariable ELSE 0 END
给你一个超级解决方案:
ALTER TABLE dbo.Status ALTER COLUMN DeviceSerial int NOT NULL
不会抛出异常,让您可以随时修复数字,并且您不必使用 instead-of 触发器或存储过程编写任何伪视图并重写来自客户端的调用。
在这种情况下,我建议使用字符串而不是数值,这种情况很少见。序列号通常是指一组唯一的字符,可以是数字和字母。通常它可能有前导零,这对数值没有任何意义,但它是唯一字符串的常规和持久部分。
我在 Windows 7.
上使用 MS-SQL Server 2014
在数据库中,我目前有一个名为 "STATUS" 的 table,其中一列的定义如下:
DeviceSerial smallint
这个table中有are/will条记录超过6k条。
不幸的是,有些设备使用错误的序列号进行编程,例如 43776 而不是 4376(技术人员输入了两次 7...)。通常,DeviceSerial 值应在范围内:1 - 9999.
显然,43776 是 smallint 的超出范围的值,因此 insert/update 操作崩溃:(
嗯,问题是:在这种情况下,有没有办法让 sql 服务器检查 inserted/updated 值,如果 DeviceSerial 值大于9999,填0? (0 表示未设置序列号或其他内容)。
您可以在 table 中使用约束,这样,如果有人尝试更新或插入超出范围的值,您就会收到错误消息。它会用正确的数据维护你的数据库,并且以后没有序列号的设备不会有问题。
ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
DeviceSerial >= 1 AND DeviceSerial <= 9999--Inclusive
)
或
ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
DeviceSerial BETWEEN 1 AND 9999
)
如果您有 SQL Server 2012+,您可以使用 TRYPARSE 或 TRYCONVERT。
如果 TRYPARSE 无法将输入的值转换为请求的数据类型,则它 returns NULL,可以合并为零。
因此,如果您尝试将 @MyVariable
插入到 smallint 中,您可以将其放入插入语句中:
COALESCE(TRYPARSE(@MyVariable AS smallint),0)
插入不会出错,如果无法将值插入到 smallint 列,则会插入一个零。
如果您不仅要强制一个值在 smallint 范围内,而且要在特定范围 1-9999 内,您可以使用 CASE 表达式来实现:
CASE WHEN @MyVariable BETWEEN 1 AND 9999 THEN @MyVariable ELSE 0 END
给你一个超级解决方案:
ALTER TABLE dbo.Status ALTER COLUMN DeviceSerial int NOT NULL
不会抛出异常,让您可以随时修复数字,并且您不必使用 instead-of 触发器或存储过程编写任何伪视图并重写来自客户端的调用。
在这种情况下,我建议使用字符串而不是数值,这种情况很少见。序列号通常是指一组唯一的字符,可以是数字和字母。通常它可能有前导零,这对数值没有任何意义,但它是唯一字符串的常规和持久部分。