SQL Server:启用触发器时创建记录失败

时间:2017-04-07 05:05:35

标签: sql-server ms-access triggers

我有一个非常古老的应用程序,我必须支持。我推动(努力)取代它,但你知道管理层是什么样的。前端位于Access 97中,它在SQL Server 2008 R2中链接了表以进行数据存储。

它已经运作了很多年,我通常拒绝修改它。

每当在特定表格中创建新记录时,我都会被要求发送自动电子邮件。我过去一直在发送来自SQL Server代理作业的电子邮件,所以我认为在创建记录时从触发器发送电子邮件并不困难,因此无需更改Access97前端

我已经创建了我的触发器,内置了大量的日志记录,因此我可以判断它是否已经过了一段时间,但它并没有。

我在客户端上收到的错误消息是

  

" ODBC - 在链接表格上插入' dbo_Quote'失败"

这是插入的表和带触发器的表。

我会在这里发布触发器代码,如果有人真的想看到它,但我不认为问题在那里。我的所有调试代码都有点长。

为了证明它有效,我注释掉了所有这样的行

set @MASuburb = (select Rtrim(MASuburb) from inserted)

并在声明代码在直接运行时有效时手动设置变量。

删除测试更改后,我在禁用触发器的情况下运行应用程序,并使用SQL Server Profiler捕获已执行的查询并插入成功。

然后我删除了创建的记录,再次启用了我的触发器。

在Management Studio中粘贴捕获的查询,然后端到端运行并发送电子邮件。只有当查询直接来自Access时才会出现问题。

如果触发器已启用,我无法弄清楚为什么SQL Server会将失败消息发送回Access。

我一直在寻找一些更好的错误消息,但似乎没有任何记录在任何地方。

有没有人有任何想法如何找到问题?

(是的,我知道摆脱Access)

提前致谢 大卫

更新 这是触发器代码。我删除了大部分调试日志。

USE [Quote]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[NewManagementQuotationEmail] 
   ON  [Quote].[dbo].[Quote]  
   AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Declare Fields Used
    Declare @DateEntered        datetime
    set @DateEntered = ''
    Declare @ContactName        nvarchar(50)
    set @ContactName = ''
    Declare @PreparedFor        nvarchar(50)
    set @PreparedFor = ''
    Declare @MailAddress1       nvarchar(50)
    set @MailAddress1 = ''
    Declare @MailAddress2       nvarchar(50)
    set @MailAddress2 = ''
    Declare @MASuburb           nvarchar(50)
    set @MASuburb = ''
    Declare @MAState            nvarchar(3)
    set @MAState = ''
    Declare @MAPcode            nvarchar(10)
    set @MAPcode = ''
    Declare @SPNumber           nvarchar(10)
    set @SPNumber = ''
    Declare @SPAddress1         nvarchar(50)
    set @SPAddress1 = ''
    Declare @SPAddress2         nvarchar(50)
    set @SPAddress2 = ''
    Declare @SPSuburb           nvarchar(50)
    set @SPSuburb = ''
    Declare @SPState            nvarchar(3)
    set @SPState = ''
    Declare @SPPcode            nvarchar(10)
    set @SPPcode = ''
    Declare @NumberOfUnits      int
    set @NumberOfUnits = ''
    Declare @PricePerUnit       money
    set @PricePerUnit = ''
    Declare @TotalAnnualFee     money
    set @TotalAnnualFee = ''
    Declare @Stationary         money
    set @Stationary = ''
    Declare @ContactPhoneW      nvarchar(15)
    set @ContactPhoneW = ''
    Declare @ContactPhoneH      nvarchar(15)
    set @ContactPhoneH = ''
    Declare @ContactPhoneM      nvarchar(15)
    set @ContactPhoneM = ''
    Declare @Fax                nvarchar(15)
    set @Fax = ''
    Declare @Email              nvarchar(50)
    set @Email = ''
    Declare @WhyChooseUs        nvarchar(50)
    set @WhyChooseUs = ''
    Declare @CurrentlyManagedBy nvarchar(50)
    set @CurrentlyManagedBy = ''
    Declare @DateSent           datetime
    set @DateSent = ''
    Declare @CallBackDate       datetime
    set @CallBackDate =''
    Declare @EnteredBy          nvarchar(15)
    set @EnteredBy = ''

    -- Setup Debug Logging 
    Declare @Debug int
    -- 0=OFF >=1 ON --
    Set @Debug = 2

    if @Debug > 0
    Begin
        DECLARE @cmd varchar(255)
        DECLARE @var varchar(255)
        DECLARE @logfile char(50)
        SET @logfile =  '>> C:\temp\NewManagementQuotationEmailLog.txt' 
        SET @var = cast(GetDate()as varchar)+ ': ' + '======= Trigger NewManagementQuotation Trigger Executed ======= (Quote Database, Quote Table)'
        SET @cmd = 'echo ' + @var + @logfile
        EXEC master..xp_cmdshell @cmd
    End
    Return
    --=======================================================================================
    -- Declare the variable to send the email

    Declare @VAR_EmailAddress varchar(100)
    Declare @VAR_Subject varchar(100)
    Declare @VAR_Body  varchar(4000)
    --Declare @VAR_FileName varchar(50)
    Declare @NewLine varchar(10)
    Set @NewLine = CHAR(13)+CHAR(10)

    set @VAR_EmailAddress = '<My Email Goes here>'
    set @DateEntered = (select DateEntered from inserted)
    set @ContactName = (select Rtrim(ContactName) from inserted)
    set @PreparedFor = (select Rtrim(PreparedFor) from inserted)
    set @MailAddress1 = (select Rtrim(MailAddress1) from inserted)
    set @MailAddress2 = (select Rtrim(MailAddress2) from inserted)
    set @MASuburb = (select Rtrim(MASuburb) from inserted)
    set @MAState = (select Rtrim(MAState) from inserted)
    set @MAPcode = (select Rtrim(MAPcode) from inserted)
    set @SPNumber = (select Rtrim(SPNumber) from inserted)
    set @SPAddress1 = (select Rtrim(SPAddress1) from inserted)
    set @SPAddress2 = (select Rtrim(SPAddress2) from inserted)
    set @SPSuburb = (select Rtrim(SPSuburb) from inserted)
    set @SPState = (select Rtrim(SPState) from inserted)
    set @SPPcode = (select Rtrim(SPPcode) from inserted)
    set @NumberOfUnits = (select NumberOfUnits from inserted)
    set @PricePerUnit = (select PricePerUnit from inserted)
    set @TotalAnnualFee = (select TotalAnnualFee from inserted)
    set @Stationary = (select Stationary from inserted)
    set @ContactPhoneW = (select Rtrim(ContactPhoneW) from inserted)
    set @ContactPhoneH = (select Rtrim(ContactPhoneH) from inserted)
    set @ContactPhoneM = (select Rtrim(ContactPhoneM) from inserted)
    set @Fax = (select Rtrim(Fax) from inserted)
    set @Email = (select Rtrim(Email) from inserted)
    set @WhyChooseUs = (select Rtrim(WhyChooseUs) from inserted)
    set @CurrentlyManagedBy = (select Rtrim(CurrentlyManagedBy) from inserted)
    set @DateSent = (select DateSent from inserted)
    set @CallBackDate = (select CallBackDate from inserted)
    set @EnteredBy = (select Rtrim(EnteredBy) from inserted)

    --================================================================================================  
    if @Debug > 0
    Begin
            SET @var = cast(GetDate()as varchar)+ ' 2) Generate Email to Trello started'
            SET @cmd = 'echo ' + @var + @logfile
            EXEC master..xp_cmdshell @cmd
    End

    if @Debug > 0
    Begin
            SET @var = cast(GetDate()as varchar)+ ' 3.0) Query Text String Begin'
            SET @cmd = 'echo ' + @var + @logfile
            EXEC master..xp_cmdshell @cmd
    End

    Set @VAR_Subject = @SPNumber 
    set @VAR_Body = 'Date Entered= ' + cast(@DateEntered as varchar(12)) + CHAR(13)+ CHAR(10) +
                    'Contact Name= ' + @ContactName + CHAR(13)+ CHAR(10)  +
                    'Prepared for= ' + @PreparedFor + CHAR(13)+ CHAR(10)  +
                    'Mail Address 1= ' + @MailAddress1 + CHAR(13)+ CHAR(10)  +
                    'Mail Address 2= ' + @MailAddress2 + CHAR(13)+ CHAR(10)  +
                    'Mail Address Suburb= ' + @MASuburb + CHAR(13)+ CHAR(10)  +
                    'SP Address 1= ' + @SPAddress1 + CHAR(13)+ CHAR(10)  +
                    'SP Address 2= ' + @SPAddress2 + CHAR(13)+ CHAR(10)  +
                    'SP State= ' + @SPState + CHAR(13)+ CHAR(10)  +     
                    'SP Suburb='     + @SPSuburb + CHAR(13)+ CHAR(10)  +
                    'SP Post Code= ' + @SPPcode + CHAR(13)+ CHAR(10)  +
                    'Number of Units= ' + cast(@NumberOfUnits as varchar(5)) + CHAR(13)+ CHAR(10)  +
                    'Price Per Unit= ' + cast(@PricePerUnit as varchar(10)) + CHAR(13)+ CHAR(10)  +
                    'Total Annual Fee= ' + cast(@TotalAnnualFee as varchar(10)) + CHAR(13)+ CHAR(10)  +
                    'Stationary= ' + cast(@Stationary as varchar(10))  + CHAR(13)+ CHAR(10)  +
                    'Contact Phone W= ' + @ContactPhoneW + CHAR(13)+ CHAR(10)  +
                    'Contact Phone H= ' + @ContactPhoneH + CHAR(13)+ CHAR(10)  +
                    'Contact Phone M= ' + @ContactPhoneM + CHAR(13)+ CHAR(10)  +
                    'Fax= ' + @Fax + CHAR(13)+ CHAR(10)  +
                    'Email= ' + @Email + CHAR(13)+ CHAR(10)  +
                    'Why Choose Us= ' + @WhyChooseUs + CHAR(13)+ CHAR(10)  +
                    'Currently Managed by= ' + @CurrentlyManagedBy + CHAR(13)+ CHAR(10)  +
                    'Date Sent= ' + cast(@DateSent as varchar(12)) + CHAR(13)+ CHAR(10)  +
                    'Call Back Date= ' + cast(@CallBackDate as varchar(12)) + CHAR(13)+ CHAR(10)  +
                    'Entered By= ' + @EnteredBy

    if @Debug > 0
    Begin
            SET @var = cast(GetDate()as varchar)+ ' 3.9) Query Text String Complete'
            SET @cmd = 'echo ' + @var + @logfile
            EXEC master..xp_cmdshell @cmd
    End


    EXEC  msdb.dbo.sp_send_dbmail
        @recipients = @VAR_EmailAddress,
        @subject = @VAR_Subject, 
        @profile_name = 'SQL Email Profile',
        @body= @VAR_Body

    if @Debug > 0
    Begin
            SET @var = cast(GetDate()as varchar)+ ' 4) Generate Email to Trello complete'
            SET @cmd = 'echo ' + @var + @logfile
            EXEC master..xp_cmdshell @cmd
    End

    --================================================================================================

    if @Debug > 0
    Begin
            SET @var = cast(GetDate()as varchar)+ '======= Trigger NewManagementQuotation Trigger Complete ======='
            SET @cmd = 'echo ' + @var + @logfile
            EXEC master..xp_cmdshell @cmd
    End
End 

更新2 添加关键字后,错误消息没有变化&#34;返回&#34; 我的触发器日志只包含一行预期

Apr  7 2017  5:15PM: ======= Trigger NewManagementQuotation Trigger Executed ======= (Quote Database, Quote Table)   

只是为了确保清楚。我可以捕获禁用触发器的Access生成的SQL,并在启用触发器的情况下直接在Microsoft Management Studio中再次运行它并且它可以正常工作。所以在我看来,Access是错误解释SQL Server的返回代码,当启用触发器时,SQL Server如何返回错误的代码。这就是我需要弄清楚的。

更新3 这是我在SQL Profiler中捕获的Access生成的SQL

    exec sp_executesql  N'INSERT INTO  "dbo"."Quote"  
(
    "DateEntered",
    "ContactName",
    "PreparedFor",
    "MailAddress1",
    "MASuburb",
    "MAState",
    "MAPcode",
    "SPNumber",
    "SPAddress1",
    "SPSuburb",
    "SPState",
    "SPPcode",
    "NumberOfUnits",
    "PricePerUnit",
    "Stationary",
    "ContactPhoneW",
    "ContactPhoneH",
    "ContactPhoneM",
    "Email",
    "WhyChooseUs",
    "CurrentlyManagedBy",
    "DateSent",
    "CallBackDate",
    "StatusId",
    "EnteredBy"
) 
VALUES (@P1,@P2,@P3,@P4,@P5,@P6,@P7,@P8,@P9,@P10,@P11,@P12,@P13,@P14,@P15,@P16,@P17,@P18,@P19,@P20,@P21,@P22,@P23,@P24,@P25)',N'
    @P1 datetime,
    @P2 char(50),
    @P3 char(50),
    @P4 char(50),
    @P5 char(50),
    @P6 char(3),
    @P7 char(10),
    @P8 char(10),
    @P9 char(50),
    @P10 char(50),
    @P11 char(3),
    @P12 char(10),
    @P13 int,
    @P14 decimal(19,4),
    @P15 decimal(19,4),
    @P16 char(15),
    @P17 char(15),
    @P18 char(15),
    @P19 char(50),
    @P20 char(50),
    @P21 char(50),
    @P22 datetime,
    @P23 datetime,
    @P24 int,
    @P25 char(15)',

'2017-04-07 00:00:00',
'Farley Bainsworth                                 ',
'Bob Johnson                                       ',
'15 Boburgal Ave                                   ',
'Kirrawee                                          ',
'NSW','2232      ',
'101010    ',
'100 Armdale Rd                                  ',
'The Land                                            ',
'NSW','2460      ',
100,
50.0000,
500.0000,
'02 66493300    ',
'02 66493693    ',
'0418256742     ',
'bobpollard@gmail.com                             ',
'Why Not                                           ',
'Bob the Builder                                   ',
'2017-04-07 00:00:00',
'2017-08-07 00:00:00',1,
'bpollard       '
go

2 个答案:

答案 0 :(得分:0)

表dbo_quote上的后插入(假设)触发器是否包含另一个具有触发器的表的插入?如果是这样,您可以检查使用变量的插入代码。

答案 1 :(得分:0)

不是答案,而是更多的结论。

我决定放弃Access,并与我的老板讨论在Visual Studio中重新开发应用程序。

这造成了许多新问题,但至少我们将在本世纪使用软件之前一半:)

感谢您的意见和建议。