.NET TimeSpan的T-SQL检查约束?

时间:2009-02-04 18:54:13

标签: sql sql-server regex parsing timespan

我在sql server 2005表中有一个nvarchar(max)列,用于存储.NET TimeSpan对象的字符串表示。有时会手动编辑表格。我想添加一个检查约束来验证TimeSpan.Parse()可以解析该字符串。我该怎么做?我想我可以使用其中一种方法在sql server中启用正则表达式,但我想找到一种更简单的方法,如果有的话!

3 个答案:

答案 0 :(得分:6)

使用TimeSpan的int属性,存储.Net Timespans的更好方法是.Ticks列。

当然,这会打破手动表格编辑。但无论如何,手动表编辑都是邪恶的。确保TimeSpan.Parse()有效或者您具有有效值的最佳方法是使用相关函数提供客户端应用程序以完成编辑。

最后,如果必须这样做,请尝试构建一个使用TimeSpan.Parse()进行测试的clr用户定义函数。然后看看你是否可以在约束中包含该函数(如果允许udf(特别是clr udf),我真的不知道我的头脑。)

答案 1 :(得分:1)

我同意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)
)

答案 2 :(得分:0)

在SQL中存储TimeSpan值有两种合理的方法。作为首选bigint中的刻度,或者作为varchar(26)中的字符串。如果它在bigint中存储为100纳秒刻度,则自然会限制为TimeSpan的适当数字范围。 (TimeSpan.Ticks是C#中的long。)

如果将其存储为字符串,则该值必须介于-10675199.02:48:05.4775808和10675199.02:48:05.4775807之间。验证这个的最简单方法是转换为刻度。如果转换成功,则值很好。

请参阅我对What is the correct SQL type to store a .Net Timespan with values > 24:00:00?的回答,了解在SQL中执行TimeSpan操作的函数。

安装完这些功能后,可以使用以下代码作为模板轻松创建约束,您可以根据需要进行更改:

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