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

.NET TimeSpan的T-SQL检查约束?,sql,sql-server,regex,parsing,timespan,Sql,Sql Server,Regex,Parsing,Timespan,我在SQLServer2005表中有一个nvarcharmax列,用于存储.NETTimeSpan对象的字符串表示形式。有时该表是手动编辑的。我想添加一个check约束来验证TimeSpan.Parse是否可以解析该字符串。我该怎么做?我想我可以使用其中一种方法在sql server中启用正则表达式,但如果有,我想找到一种更简单的方法 存储.Net Timespans的更好方法是使用TimeSpan的.Ticks属性在int列中存储 当然,这打破了手工编辑表格的习惯。但不管怎样,手工编辑表格是有

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

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

当然,这打破了手工编辑表格的习惯。但不管怎样,手工编辑表格是有害的。确保TimeSpan.Parse工作或您具有有效值的最佳方法是使用相关函数提供客户端应用程序以完成编辑


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

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

当然,这打破了手工编辑表格的习惯。但不管怎样,手工编辑表格是有害的。确保TimeSpan.Parse工作或您具有有效值的最佳方法是使用相关函数提供客户端应用程序以完成编辑


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

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

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

在SQL中存储TimeSpan值有两种合理的方法。作为bigint中的记号(首选),或作为varchar26中的字符串。如果它以100纳秒的刻度存储在一个bigint中,它自然会被限制在一个时间范围内的适当数字范围内。TimeSpan.Ticks在C中是一个长字符

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

有关在SQL中执行时间跨度操作的函数,请参见我的答案

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

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

在SQL中存储TimeSpan值有两种合理的方法。作为bigint中的记号(首选),或作为varchar26中的字符串。如果它以100纳秒的刻度存储在一个bigint中,它自然会被限制在一个时间范围内的适当数字范围内。TimeSpan.Ticks在C中是一个长字符

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

有关在SQL中执行时间跨度操作的函数,请参见我的答案

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

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

滴答声是否太依赖环境?我认为存储毫秒会更好。时间跨度刻度被定义为100纳秒。不依赖环境。与处理器周期不同,处理器周期显然是.TimeSpan.MaxValue.Ticks产生9223372036854775807。TimeSpan.MinValue.Ticks收益率-9223372036854775808。必须使用bigint正确存储TimeSpan.Ticks值.are not.t
ICK过于依赖环境?我认为存储毫秒会更好。时间跨度刻度被定义为100纳秒。不依赖环境。与处理器周期不同,处理器周期显然是.TimeSpan.MaxValue.Ticks产生9223372036854775807。TimeSpan.MinValue.Ticks收益率-9223372036854775808。必须使用bigint正确存储TimeSpan.Ticks值。