SQL Server插入触发器改进
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server插入触发器改进相关的知识,希望对你有一定的参考价值。
需要:从“评论类型”文本/备注字段中获取数据,并在记录插入时将其放入单独的字段中。下面的示例使用字段TimeStamp来简化但是使用了更新AFTER记录(低效)而不是插入记录时。需要这样做而不更新。
解决方案:之前从未使用过SQL触发器,经过多次哀嚎和咬牙切齿之后,终于想出了一些东西。它有效 - 但效率很低。有没有更好的办法?
示例:想象一个表格(Castings),其格式为:“2017-12-10 18:44:54”。插入记录后,将使用TimeStamp字段上的子字符串通过触发器自动填充字段。在这种情况下,YYYY =“2017”,MM =“12”,DD =“10”,HH =“18”,MN =“44”,SS =“54”。使用名为SQLBuddy的触发器。
架构:
ID bigint (Identify Specification YES auto-increment)
TimeStamp char(19)
YYYY char(4)
MM char(2)
DD char(2)
HH char(2)
MN char(2)
SS char(2)
SQL TRIGGER代码:
USE [SERT]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[SQLBuddy]
ON [dbo].[Castings]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE Castings
SET YYYY = SUBSTRING(TimeStamp,1,4), MM = SUBSTRING(TimeStamp,6,2), DD = SUBSTRING(TimeStamp,9,2), HH = SUBSTRING(TimeStamp,12,2), MN = SUBSTRING(TimeStamp,15,2), SS = SUBSTRING(TimeStamp,18,2);
SELECT TOP 1 ID FROM Castings ORDER BY ID DESC
END
您最好的选择是完全避免触发并在表上使用计算列。像这样:
CREATE TABLE YourTable
(ID bigint IDENTITY (1,1),
YourDateTime DATETIME,
dYear as DATEPART(YEAR, YourDateTime),
dMonth as DATEPART(MONTH, YourDateTime),
dDay as DATEPART(DAY, YourDateTime),
dHour as DATEPART(HOUR, YourDateTime),
dMinute as DATEPART(MINUTE, YourDateTime),
dSecond as DATEPART(SECOND, YourDateTime)
);
Click here for SQL Fiddle Example
为什么要将时间戳分解为单个组件?
更糟糕的是,为什么要将这些组件存储为字符?
为了说明,基于您的架构,下个月数字的顺序是什么?
'1'
'2'
'10'
'11'
答案是:
January
October
November
February
对单独的组件使用整数将确保正确的排序顺序,但你仍然会遇到很多繁琐的逻辑。
假设你有
YYYY=2017
MM=12
DD=31
如果你加一天会怎么样?
如果您的时间戳以字符串形式出现,请将其转换为日期时间数据类型。稍后您将通过拥有有用的有效时间戳来节省这么多头痛。此外,您不需要触发器来分离碎片。只需将整个时间戳插入单个字段即可。
以上是关于SQL Server插入触发器改进的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 MVC4 SQL Server 的实体框架插入后触发器不会触发