.NET TimeSpan 的 T-SQL 检查约束?
Posted
技术标签:
【中文标题】.NET TimeSpan 的 T-SQL 检查约束?【英文标题】:T-SQL check constraint for .NET TimeSpan? 【发布时间】:2009-02-04 18:54:13 【问题描述】:我在 sql server 2005 表中有一个 nvarchar(max) 列,用于存储 .NET TimeSpan 对象的字符串表示形式。有时表格是手动编辑的。我想添加一个检查约束来验证字符串是否可以被 TimeSpan.Parse() 解析。我该怎么做?我想我可以使用其中一种方法在 sql server 中启用正则表达式,但如果有的话,我想找到一种更简单的方法!
【问题讨论】:
【参考方案1】:使用 TimeSpan 的 .Ticks
属性存储 .Net 时间跨度的更好方法是在 int
列中。
当然,这会破坏手动表格编辑。但是手动表格编辑无论如何都是邪恶的。确保 TimeSpan.Parse() 有效或您具有有效值的最佳方法是提供使用相关功能的客户端应用程序来完成您的编辑。
最后,如果您必须这样做,请尝试构建一个使用 TimeSpan.Parse() 进行测试的 clr 用户定义函数。然后看看你是否可以在你的约束中包含该函数(我真的不知道是否允许 udf(特别是 clr udf)在那里)。
【讨论】:
.Ticks 不是太依赖环境了吗?我认为存储毫秒会更好。 一个 TimeSpan 刻度定义为 100 纳秒。不依赖于环境。 (与处理器周期不同,这显然是)。TimeSpan.MaxValue.Ticks
产生 9223372036854775807。TimeSpan.MinValue.Ticks
产生 -9223372036854775808。您必须使用 bigint
正确存储 TimeSpan.Ticks
值。【参考方案2】:
我同意 Joel 的观点,如果可能的话,您应该尝试摆脱直接的表格编辑。我还要补充一点,将数据库如此紧密地耦合到前端代码通常不是一个好主意。以最适合数据库的方式存储数据,并根据需要将其转换为任何前端代码。
如果你不能,那么也许这第一次尝试会让你接近。它不允许 Timespan.Parse 的完整精度,因为 ISDATE() 函数只接受最接近 1000 秒的时间。也许你可以建立在它之上。像我以前那样去掉第二部分,然后分别检查。虽然这是一种表达方式。
CREATE TABLE dbo.Test_Timespan
(
my_string NVARCHAR(MAX) NOT NULL,
CONSTRAINT CK_Test_Timespan_my_string CHECK (CAST(SUBSTRING(RTRIM(LTRIM(my_string)), 1, CHARINDEX('.', RTRIM(LTRIM(my_string))) - 1) AS INT) BETWEEN -10675199 AND 10675199 AND ISDATE(SUBSTRING(RTRIM(LTRIM(my_string)), CHARINDEX('.', RTRIM(LTRIM(my_string))) + 1, LEN(my_string) - CHARINDEX('.', RTRIM(LTRIM(my_string))))) = 1)
)
【讨论】:
【参考方案3】:在 SQL 中存储TimeSpan
值有两种合理的方法。作为首选 bigint
中的刻度,或作为 varchar(26) 中的字符串。如果它在bigint
中存储为 100 纳秒滴答声,它自然会被限制在 TimeSpan 的适当数字范围内。 (TimeSpan.Ticks
是 C# 中的 long
。)
如果存储为字符串,则该值必须介于 -10675199.02:48:05.4775808 和 10675199.02:48:05.4775807 之间。验证这一点的最简单方法是转换为刻度。如果转换成功,则价值良好。
有关在 SQL 中执行 TimeSpan 操作的函数,请参阅我对 What is the correct SQL type to store a .Net Timespan with values > 24:00:00? 的回答。
安装这些功能后,可以使用以下代码作为模板轻松创建约束,您可以根据需要进行更改:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TimeSpanStringTest](
[ID] [int] IDENTITY(1,1) NOT NULL,
[TimeSpanString] [varchar](26) NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[TimeSpanStringTest] WITH CHECK ADD CONSTRAINT [CK_TimeSpanString] CHECK (([dbo].[ConvertFromTimeSpanString]([TimeSpanString]) IS NOT NULL))
GO
ALTER TABLE [dbo].[TimeSpanStringTest] CHECK CONSTRAINT [CK_TimeSpanString]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Validates a TimeSpan string by trying to convert it to ticks.' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'TimeSpanStringTest', @level2type=N'CONSTRAINT',@level2name=N'CK_TimeSpanString'
GO
【讨论】:
以上是关于.NET TimeSpan 的 T-SQL 检查约束?的主要内容,如果未能解决你的问题,请参考以下文章
protobuf-net:不正确的线型反序列化 TimeSpan