到目前为止,我已经花了大约 30 个小时努力sp_send_dbmail去上班。我终于得到了一些工作,但我严重怀疑它的安全性。我想知道一种更好但快速且易于设置的方法(此时我的时间受到严重限制),以及“理想”(最佳实践)解决方案。
当前 SQL Server 2005 配置
- `After Insert` Trigger on table executes `sp_send_dbmail`
- Database Mail SMTP Account setup (with successful mail test)
- Database Mail Profile setup (with "Public Profile" ticked)
- "guest" account added to "DatabaseMailUserRole"
Run Code Online (Sandbox Code Playgroud)
我发现这篇文章提出了“正确”的解决方案,我阅读了这篇文章,在那里我发现这是一个非常复杂的解决方案,似乎有太多可能出错的事情,更不用说难以维护了。
我对替代解决方案的想法是这些。
1. Setup an Application Role in msdb (this would be my first time using one
and not even sure if it IS a solution :P), and use it to ensure that …Run Code Online (Sandbox Code Playgroud) 目前正在基于在特定表更新时触发的触发器进行数据库审计项目。触发器将更改写入表;写入的信息有:表名、更新列、时间戳、用户、旧值和新值。
触发器适用于单个更新,但当涉及多行更新时,它不起作用。
我的代码是这样的:
IF (UPDATE(Priority))
BEGIN
SET @UpdatedColumn = 'Priority'
INSERT INTO dbo.AuditTable
( [TableName] ,
[Source] ,
[RecordId] ,
[User] ,
[TimeStamp] ,
[UpdatedColumn] ,
[OldValue] ,
[NewValue]
)
SELECT
N'BookingItem' , -- TableName - nvarchar(max)
(SELECT CODE FROM TBL_LEG_SOURCE
INNER JOIN INSERTED INS ON LEG_SOURCE_ID = INS.SourceId) ,
INS.Id , -- RecordId - bigint
(SELECT USERNAME FROM INSERTED
INNER JOIN TBL_USER
ON ModifiedById = USER_ID) , -- User - nvarchar(max)
GETDATE() , -- TimeStamp - datetime
@UpdatedColumn , …Run Code Online (Sandbox Code Playgroud) 我有一个用于存储事件的 SQL Server 表。
我只希望表包含最近添加的 1000 行,当插入第 1001 行时,应删除第 1 行。
我有一个 DateCreatedUTC 列和一个自动编号列......我可以编写一个查询来执行删除并触发它,INSERT但我不知道这是最合适的解决方案。
我最近从 SQL Server 2005 升级到 2012。但是在验证过程中,发现了一个错误。
某个触发器的编码如下:
CREATE TRIGGER [dbo].[trigger] on [dbo].[foo]
FOR UPDATE, UPDATE
AS
UPDATE foobar
SET datetime = GetDate()
FROM bar
WHERE foobar.id = bar.id
GO
Run Code Online (Sandbox Code Playgroud)
我可以在 SQL Server 2005 上安全地执行这个(奇怪的)。
但是,在 SQL Server 2012 上,它会引发(我所期望的)语法错误。
语法错误:触发器声明中操作“UPDATE”的重复规范。
为什么这不会在 SQL Server 2005 上引发语法错误?我在这方面的 google-fu 失败了。
为什么这似乎适用于 SQL Server 2005?
我试图了解我的一个表 (DocumentDistribution) 上的现有触发器,它似乎是 DocumentInfo 和 DocumentSource 表之间的桥接表。我不明白这一行 (SET....FROM INSERTED) 是如何从中获取值的?这就是所谓的动态 SQL,它根据用户的选择从前端应用程序中获取该数据库的值吗?
我在尝试测试时遇到错误,因为子查询返回多行而语法期望单行,有什么建议吗?我正在使用 SQL Server 2008R2。
Alter TRIGGER [dbo].[DocDist_Dup_Check]
ON [dbo].[DocumentDistribution]
AFTER UPDATE, INSERT
AS
BEGIN
SET NOCOUNT ON;
SET ANSI_WARNINGS OFF;
DECLARE @docid int,
@sourceid int,
@errstr varchar(255);
SET @errstr = 'The distribution you have attempted to create already exists in the database.' + CHAR(13) +
'Duplicate distributions are not allowed for any document source except eBinder.';
SET @docid = (SELECT DocumentDistDocID FROM INSERTED);
SET @sourceid = (SELECT DocumentDistSourceID FROM …Run Code Online (Sandbox Code Playgroud) 我有一个关于触发器性能的问题。
CREATE TABLE [dbo].[_test](
[ID] [INT] IDENTITY(1,1) NOT NULL,
[Date] [DATETIME] NULL,
[DateYearID] [INT] NULL,
[DateQuarterID] [INT] NULL,
[Date1] [DATETIME] NULL,
[Date1YearID] [INT] NULL,
[Date1QuarterID] [INT] NULL)
Run Code Online (Sandbox Code Playgroud)
现在我想要触发器,如果我更新 Date 列(或插入新行),必须更新 DateYearID 和 DateQuarterID 列,如果我更新 Date1 列(或插入新行),则必须更新 Date1YearID 和 Date1QuarterID 列。有什么更好的,有一个触发器,比如
IF UPDATE(DATE)
UPDATE _test SET DateYearID = ... , DateQuarterID = ...
IF UPDATE (DATE1)
UPDATE _test SET Date1YearID = ... , Date1QuarterID = ...
Run Code Online (Sandbox Code Playgroud)
或者有两个不同的触发器,第一个更新 DateYearID,DateQuarterID 列,第二个更新 DateYear1ID,DateQuarter1ID 列。
我正在使用 SQL Server 2014。
非常感谢您的帮助。
我有 2 个插入后触发器和 1 个而不是插入触发器的问题。After Insert 触发器应该执行一些操作,但不会触发这些操作。
当替代触发器触发时,它们的动作 After Triggers 工作正常。
让我解释:
“替代”触发器验证该ID值是否为 Null。如果是,则触发器在表 ( TRADE_APPR) 中执行插入操作,填充IDSQL Server 序列中的值。
当替代触发器执行操作时,插入后触发器也执行它们的操作。
我的而不是插入触发器的代码是这样的:
ALTER TRIGGER [ConfirmMgr].[TG_TRADE_APPR_BER_I]
ON [ConfirmMgr].TRADE_APPR]
INSTEAD OF INSERT
AS
DECLARE
@user_name varchar(50),
@appr_username varchar(50),
@appr_id int,
@v_id int,
@appr_timestamp datetime
BEGIN
SELECT @appr_username = APPR_BY_USERNAME FROM inserted
IF (@appr_username) IS NULL
BEGIN
SELECT @user_name = SUSER_NAME()
UPDATE tbl SET APPR_BY_USERNAME = UPPER(@user_name)
FROM ConfirmMgr.TRADE_APPR tbl
INNER JOIN inserted i ON tbl.ID = i.ID
END …Run Code Online (Sandbox Code Playgroud) 给定与 DDL 命令对应的字符串,我如何确定它是哪个 DDL 命令(列添加、约束添加等)?
我在数据库上有一个 DDL 触发器,只要数据库中的任何表被更改,就会触发它;系统表将记录在数据库中的任何表上触发的 DDL 命令。
所以命令看起来像:
1. ALTER TABLE [dbo.table] ADD [column] VARCHAR(20) NULL;
2. ALTER TABLE [dbo.table] ADD [column] VARCHAR(20) NULL CONSTRAINT [cons] UNIQUE;
3. ALTER TABLE [dbo.table] WITH NOCHECK ADD CONSTRAINT [cons] CHECK ([column] > 1);
4. ALTER TABLE [dbo.table] WITH NOCHECK ADD [column1] VARCHAR(20) NULL,
CONSTRAINT [cons] CHECK ([column] > 1);
Run Code Online (Sandbox Code Playgroud)
以上4条DDL语句有什么办法辨别吗?我只对将新列添加到表中的 DDL 感兴趣,并且希望仅检索此新列的名称和数据类型。
到目前为止,我一直在使用诸如SUBSTRING(), 之类的函数LEN(),CHARINDEX()但运气不佳。
附言。我的触发器能够获取正在执行 DDL 的表的名称。
触发器将简单地将上述 4 个选项之一作为输入,并且需要区分何时发生了列更改,并且只检索新列名及其对应的数据类型。
在对表进行更改之后,触发器将被触发,这个确切的更改命令被记录在一个系统表中,作为我用来跟踪更改的 CDC 功能的一部分(限制我对命令的访问)。这个 CDC …
好的,所以我试图在最初插入记录时将特定记录中的列更新为 CURRENT_TIMESTAMP。这就是我所拥有的,否则我就迷路了。
CREATE TRIGGER dbo.TrgUpnInsert
ON [CNLH Security Authentication].dbo.DateTimestamp
AFTER INSERT,
INSERT INTO [CNLH Security Authentication].dbo.EntranceInformation (DateTimestamp) Values (CURRENT_TIMESTAMP);
Run Code Online (Sandbox Code Playgroud) I have a projects table:
+------------+-----+
| PROJECT_ID | ... |
+------------+-----+
| LC000001 | |
| LC000002 | |
| LC000003 | |
| LC000004 | |
| LC000005 | |
+------------+-----+
Run Code Online (Sandbox Code Playgroud)
As you can see, the PROJECT_ID column has a text datatype (NVARCHAR2) and it has a prefix (LC).
I'm guessing that creating an ID with a prefix might have been a been a poor design choice. But, right or wrong, this is how …