SQL Server插入触发器改进

时间:2017-12-21 16:33:41

标签: sql sql-server triggers insert substring

需要: 从“注释类型”文本/备注字段中获取数据,并在记录插入时将其放入单独的字段中。下面的示例使用字段TimeStamp来简化但是使用了更新AFTER记录(低效)而不是插入记录时。需要在没有更新的情况下执行此操作。

: 从来没有使用过SQL触发器,在经过多次哀嚎和咬牙切齿之后,终于想出了一些东西。它有效 - 但效率很低。还有更好的方法吗?

示例: 想象一下使用TimeStamp字段格式化的表格(Castings):“2017-12-10 18:44:54”。插入记录后,将使用TimeStamp字段上的子字符串通过触发器自动填充字段。在这种情况下,YYYY =“2017”,MM =“12”,DD =“10”,HH =“18”,MN =“44”,SS =“54”。使用名为SQLBuddy的触发器。

SCHEMA:

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 CODE:

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

2 个答案:

答案 0 :(得分:2)

您最好的选择是完全避免触发并在您的桌子上使用计算列。像这样:

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 :(得分:0)

为什么要将时间戳分解为单个组件?

更糟糕的是,为什么要将这些组件存储为字符?

为了说明,根据您的架构,下个月数字的顺序是什么?

'1'
'2'
'10'
'11'

答案是:

January
October
November
February

对单独的组件使用整数将确保正确的排序顺序,但是你仍会遇到很多繁琐的逻辑。

假设你有

YYYY=2017
MM=12
DD=31

如果你加一天会怎么样?

如果您的时间戳以字符串形式出现,请将其转换为日期时间数据类型。稍后您将通过拥有有用的有效时间戳来节省这么多头痛。此外,您不需要触发器来分离碎片。只需将整个时间戳插入一个字段即可。