1

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

4

3 回答 3

6

存储 .Net 时间跨度的更好方法是int使用 TimeSpan 的.Ticks属性在列中。

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

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

于 2009-02-04T19:16:33.443 回答
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)
)
于 2009-02-04T19:26:51.377 回答
0

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

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

请参阅我对存储值 > 24:00:00 的 .Net 时间跨度的正确 SQL 类型是什么的回答?用于在 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
于 2017-06-29T17:58:08.230 回答