【问题标题】:How to create a SQL trigger to update a date field on one table when another table is updated如何创建 SQL 触发器以在更新另一个表时更新一个表上的日期字段
【发布时间】:2019-01-21 08:50:08
【问题描述】:

我想在我的数据库中创建一个触发器,它应该在表“阀门”更新时运行。

作为触发的一部分,必须发生以下情况:

  1. ME 表应根据 Valve 表的 Schema [PnPID, Position X/Y/Z, LineNumberTag, Tag, Spec.] 创建或更新。]
  2. 现有表 Valve 中的所有信息,将被复制/更新到表 ME 中

更改应根据源 Valve 在表 ME 中自动发生,无需任何手动干预。

请帮我创建这样一个触发器?我是 SQL 新手。

在我的表 ME.Valve 上,我想添加其他列,其中包含我不想出现在 Valve 表中的新信息(不要破坏它)。我附上一张现有表 Valve 的图片。 所以,我想要的是从我的表 SQL_P3D_Test_ME 中的表“Valve_PNP”复制,例如只有列“LineNumberTag”,“Tag”,但是当来自表“Valve_PNP”列“LineNumberTag”,“Tag”的值正在改变时,改变并自动进入我的表 SQL_P3D_Test_ME。 在我的表 SQL_P3D_Test_ME 添加新列,例如 Made By 在女巫中,我在每个阀门前面的行中手动插入信息。 有可能吗?

这就是我想要的,在“dbo.Source Tabel”表中,有一行在“TextColumn”、“ValueColumn”等列中有信息。首先,这些信息将被复制到表 [me] 中。 [目标表],但是当信息进入表格“dbo.Source Tabel”时,例如“TextColumn”列中的信息从“测试插入和更新且没有数据更改”与“Marius”更改为表格 [me] 中的更新。[目标表] 仅此信息而不添加新行。每列以此类推。

我使用 Microsoft SQL Server Management Studio

【问题讨论】:

  • 您使用的是哪个 dbms? (大多数 dbms 产品都有自己的非 ANSI SQL 版本的触发器。)
  • 表格有,而不是字段...
  • 我显然错过了这里的重点 - 拥有两个始终包含完全相同数据的表有什么意义?
  • 显而易见的解决方案(基于您在下面的“答案”详细信息)是只拥有 ME.Valve 表并拥有一个名为 Valveview 现有代码继续access and thinks 是一个表。假设视图中有一个简单的选择,它将无需进一步工作即可更新。不要指望为自己工作。多次持有相同的数据只会给您带来不一致的机会。
  • 您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称,触发器是高度特定于供应商的)请为您正在使用的数据库产品添加tagpostgresqloraclesql-server、@ 987654329@, ...

标签: sql-server tsql database-trigger


【解决方案1】:

我建议将触发器添加到包含对“ME.Valve”表的更新的“Valve”表中。让我知道是否应该编写语法示例。

这是我的解决方案的一个示例..

USE [SpecifyYourDatabaseHere]

CREATE TABLE dbo.SourceTable
    (
    SourcePrimaryKeyID INT IDENTITY PRIMARY KEY,
    TextColumn VARCHAR(2048),
    ValueColumn DECIMAL(18,3),
    NumberColumn INT
    )

CREATE TABLE [me].[DestinationTable]
    (
    DestinationPrimaryKeyID INT IDENTITY PRIMARY KEY,
    SourcePrimaryKeyID INT,
    TextColumn VARCHAR(2048),
    ValueColumn DECIMAL(18,3),
    NumberColumn INT,
    ActionType VARCHAR(100),
    CreatedDate AS GETDATE(), -- Default to current date
    CreatedDatabaseUser AS SUSER_SNAME()
    )

GO

-- You will need an insert, update and delete trigger.

-- INSERT TRIGGER

-- This trigger will insert any new records into the destination table.
CREATE TRIGGER [dbo].[SourceTable_Insert]
ON [dbo].[SourceTable]
FOR INSERT

AS 

INSERT INTO [me].[DestinationTable] 
    (
    SourcePrimaryKeyID,
    TextColumn,
    ValueColumn,
    NumberColumn,
    ActionType
    )
SELECT  INSERTED.SourcePrimaryKeyID,
        INSERTED.TextColumn,
        INSERTED.ValueColumn,
        INSERTED.NumberColumn,
        'Insert' AS ActionType
FROM    INSERTED

GO

-- UPDATE TRIGGER

-- Conditional Update Trigger : This trigger will only insert data in destination of any of the values in the data columns has changed (Saves space).
CREATE TRIGGER [dbo].[SourceTable_Update]
ON [dbo].[SourceTable]
FOR UPDATE

AS 

INSERT INTO [me].[DestinationTable] 
    (
    SourcePrimaryKeyID,
    TextColumn,
    ValueColumn,
    NumberColumn,
    ActionType
    )
SELECT  INSERTED.SourcePrimaryKeyID,
        INSERTED.TextColumn,
        INSERTED.ValueColumn,
        INSERTED.NumberColumn,
        'Update' AS ActionType
FROM    INSERTED
        INNER JOIN
            (
            SELECT  SourcePrimaryKeyID,TextColumn,ValueColumn,NumberColumn
            FROM    [me].[DestinationTable]
                    INNER JOIN
                        (
                        SELECT  MAX(DestinationPrimaryKeyID) MaxDestinationPrimaryKeyID,
                                COUNT(1) DestinationRecordCount
                        FROM    [me].[DestinationTable]
                                INNER JOIN
                                    INSERTED ON
                                        [me].[DestinationTable].SourcePrimaryKeyID = INSERTED.SourcePrimaryKeyID
                        GROUP BY
                            [me].[DestinationTable].SourcePrimaryKeyID
                        ) MaxDestinationPrimaryKey ON
                        MaxDestinationPrimaryKey.MaxDestinationPrimaryKeyID = [me].[DestinationTable].DestinationPrimaryKeyID
            ) DestinationData ON
                DestinationData.SourcePrimaryKeyID = INSERTED.SourcePrimaryKeyID
                AND (
                        ISNULL(DestinationData.TextColumn,'') != ISNULL(INSERTED.TextColumn,'') OR 
                        ISNULL(DestinationData.ValueColumn,0) != ISNULL(INSERTED.ValueColumn,0) OR 
                        ISNULL(DestinationData.NumberColumn,0) != ISNULL(INSERTED.NumberColumn,0)
                    )

GO

-- DELETE TRIGGER

-- This trigger will insert any deleted records into the destination table.

CREATE TRIGGER [dbo].[SourceTable_Delete]
ON [dbo].[SourceTable]
FOR DELETE

AS 

INSERT INTO [me].[DestinationTable] 
    (
    SourcePrimaryKeyID,
    TextColumn,
    ValueColumn,
    NumberColumn,
    ActionType
    )
SELECT  INSERTED.SourcePrimaryKeyID,
        INSERTED.TextColumn,
        INSERTED.ValueColumn,
        INSERTED.NumberColumn,
        'Delete' AS ActionType
FROM    INSERTED

GO

-- Test the code..

-- Insert trigger 
INSERT  [dbo].[SourceTable]
SELECT  'test insert and update with no data change',
        123.456,
        1

INSERT  [dbo].[SourceTable]
SELECT  'test insert and update with data changed',
        123.456,
        1

INSERT  [dbo].[SourceTable]
SELECT  'test delete',
        123.456,
        1

-- Update trigger test 1 - no data changed (Must not add record in destination)
UPDATE  [dbo].[SourceTable]
SET     NumberColumn = 1
WHERE   SourcePrimaryKeyID = 1

-- Update trigger test 2 - Data changed (Must add record in destination)
UPDATE  [dbo].[SourceTable]
SET     NumberColumn = NumberColumn + 1
WHERE   SourcePrimaryKeyID = 2

-- Deleted trigger test
DELETE FROM [dbo].[SourceTable]
WHERE   SourcePrimaryKeyID = 3

SELECT  *
FROM    dbo.SourceTable

SELECT  *
FROM    me.DestinationTable
ORDER BY
        SourcePrimaryKeyID,
        DestinationPrimaryKeyID

【讨论】:

  • 如果你好心,你可以写一个语法示例。
  • 嗨,Marius,不幸的是,我意识到您的要求不能仅靠触发器来完成。触发器用于针对表内数据的更新、插入或删除操作运行 SQL 代码。尽管它几乎可以是任何代码,但触发器将负责将数据从一个表复制到另一个表。对于涉及结构更改(例如添加的列)的情况,它并不理想。
  • 我们要添加的列将提供信息,并将在项目结束时手动完成。你想告诉我触发后我不能添加列吗?谢谢!
  • 没有。这一切都取决于触发器的作用。在您的问题中,您指出触发器需要将列更改应用于另一个表(该表具有不能影响源表的其他列)。这将具有挑战性。
  • 所以,我想要的是从我的表 SQL_P3D_Test_ME 中的表 "Valve_PNP" 复制,例如仅列 "LineNumberTag" , "Tag",但是当来自表 "Valve_PNP" 列 "LineNumberTag" 的值时, “标签”正在更改,自动更改并进入我的表 SQL_P3D_Test_ME。在我的表 SQL_P3D_Test_ME 中添加新列,例如 Made By 在女巫中,我在每个阀门前面的行中手动插入信息。有可能吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-23
  • 2011-02-10
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多