Auditing trigger - Column name or number of supplied values does not match table definition

StackOverflow https://stackoverflow.com/questions/11392143

  •  19-06-2021
  •  | 
  •  

Question

I am attempting to create a database trigger capable of creating a snapshot of a 'Transactions' table and storing it in an 'Audit' table along with information pertaining to the date of the inserting, updating or deleting of any rows of data.

Apologies in advance, but I'm very much a novice at this kinda stuff!

As it stands, my trigger is as follows:

create trigger AuditTransactions
on dbo.Transactions
after insert, update, delete
as

    if exists(select * from inserted)
    begin
        if exists(select * from deleted)
        begin
            -- this is for an update
            update Audit
            set DeleteDate = getdate()
            where TransactionId in (select TransactionId from deleted)
        end 

        -- this is just for an insert
        insert into Audit
        select *, getdate() as CreateDate
        from inserted
    end
    else
    begin
        -- this is just for a delete
        update Audit
        set DeleteDate = getdate()
        where TransactionId in (select TransactionId from deleted)
    end

go

And my audit table appears as follows:

CREATE TABLE [dbo].[Audit](
    [TransactionId] [int] NOT NULL,
    [InvoiceNumber] [nvarchar](1) NULL,
    [InvoiceType] [nvarchar](1) NULL,
    [InvoiceIssueDate] [datetime] NULL,
    [InvoiceTotalexclVat] [nvarchar](1) NULL,
    [InvoiceTotalVat] [numeric](18, 0) NULL,
    [InvoiceDiscount] [numeric](18, 0) NULL,
    [InvoiceTotalPayable] [numeric](18, 0) NULL,
    [AccountCode] [nvarchar](1) NULL,
    [Reference1] [nvarchar](1) NULL,
    [Reference2] [nvarchar](1) NULL,
    [Reference3] [nvarchar](1) NULL,
    [Level1CustomOrg] [nvarchar](1) NULL,
    [Level2CustomOrg] [nvarchar](1) NULL,
    [Level3CustomOrg] [nvarchar](1) NULL,
    [Level4CustomOrg] [nvarchar](1) NULL,
    [ScanLocation] [nvarchar](1) NULL,
    [ScanDateTime] [datetime] NULL,
    [CaptureInkjetId] [nvarchar](1) NULL,
    [CaptureBatchId] [nvarchar](1) NULL,
    [CaptureDateTime] [datetime] NULL,
    [InputSource] [nvarchar](1) NULL,
    [CurrencyCode] [nvarchar](1) NULL,
    [DebitCredit] [nvarchar](1) NULL,
    [OrderNumberHeader] [nvarchar](1) NULL,
    [SupplierName] [nvarchar](1) NULL,
    [BancPaySupplierId] [nvarchar](1) NULL,
    [SupplierIDERP] [nvarchar](1) NULL,
    [PaymentDate] [datetime] NULL,
    [DeliveryDate] [datetime] NULL,
    [CustomRef1] [nvarchar](1) NULL,
    [CustomRef2] [nvarchar](1) NULL,
    [CustomRef3] [nvarchar](1) NULL,
    [CustomRef4] [nvarchar](1) NULL,
    [CustomRef5] [nvarchar](1) NULL,
    [CustomRef6] [nvarchar](1) NULL,
    [CustomRef7] [nvarchar](1) NULL,
    [CustomRef8] [nvarchar](1) NULL,
    [CustomRef9] [nvarchar](1) NULL,
    [CustomRef10] [nvarchar](1) NULL,
    [CustomRef11] [nvarchar](1) NULL,
    [CustomRef12] [nvarchar](1) NULL,
    [CustomRef13] [nvarchar](1) NULL,
    [CustomRef14] [nvarchar](1) NULL,
    [CustomRef15] [nvarchar](1) NULL,
    [CustomAmount1] [numeric](18, 0) NULL,
    [CustomAmount2] [numeric](18, 0) NULL,
    [CustomAmount3] [numeric](18, 0) NULL,
    [CustomAmount4] [numeric](18, 0) NULL,
    [CustomAmount5] [numeric](18, 0) NULL,
    [CustomDate1] [datetime] NULL,
    [CustomDate2] [datetime] NULL,
    [Country1] [nvarchar](1) NULL,
    [Country2] [nvarchar](1) NULL,
    [Country3] [nvarchar](1) NULL,
    [Country4] [nvarchar](1) NULL,
    [Country5] [nvarchar](1) NULL,
    [Country6] [nvarchar](1) NULL,
    [Country7] [nvarchar](1) NULL,
    [Country8] [nvarchar](1) NULL,
    [Country9] [nvarchar](1) NULL,
    [Country10] [nvarchar](1) NULL,
    [CheckedOut] [bit] NULL,
    [CheckedOutDate] [datetime] NULL,
    [BlobUrl] [nvarchar](1) NULL,
    [GLCode] [nvarchar](1) NULL,
    [RejectReason] [nvarchar](1) NULL,
    [RejectComment] [nvarchar](1) NULL,
    [ReferMessage] [nvarchar](1) NULL,
    [PaymentTerms] [nvarchar](1) NULL,
    [CheckedOutByUserId] [int] NULL,
    [LastUpdatedByUserId] [int] NULL,
    [TransactionFormatTypeId] [int] NULL,
    [RequestOriginalStatusTypeId] [int] NULL,
    [GLCodeComment] [nvarchar](1) NULL,
    [SenderOrganizationId] [int] NULL,
    [ReceiverOrganizationId] [int] NULL,
    [TransactionStatusTypeId] [int] NULL,
    [TransactionTypeId] [int] NULL,
    [OrganizationId] [int] NULL,
    [OrganizationId1] [int] NULL,
    [CreateDate] [datetime] NOT NULL,
    [DeleteDate] [datetime] NULL
) ON [PRIMARY]

GO

When attempting to execute the query for the trigger I am getting the following error message:

Msg 213, Level 16, State 1, Procedure AuditTransactions, Line 17
Column name or number of supplied values does not match table definition.

This appears to be the 'insert into Audit' command, but I have no idea what to do from here!

Any help will be hugely appreciated, thanks in advance!

Was it helpful?

Solution

INSERT seems to be rather poorly documented. For the VALUES() element, it states the following:

If the values in the Value list are not in the same order as the columns in the table or do not have a value for each column in the table, column_list must be used to explicitly specify the column that stores each incoming value.

(Emphasis added)

However, it is my understanding and belief that the same constraint applies, no matter what the source of values/rows are - that unless you exactly match all columns in the table, you need to provide the column_list.

Now, for your instance, it may be easier if you just provide a value for every column in the table:

insert into Audit
select *, getdate() as CreateDate,null as DeleteDate
from inserted

Now, my other observation is that all this mucking about with conditional control flow is rather pointless - an insert of 0 rows will have no effect, and an update using in against an empty table will similarly have no effect. So I'd just have:

create trigger AuditTransactions
on dbo.Transactions
after insert, update, delete
as

    update Audit
    set DeleteDate = getdate()
    where TransactionId in (select TransactionId from deleted)

    insert into Audit
    select *, getdate() as CreateDate,null as DeleteDate
    from inserted

OTHER TIPS

 insert into Audit
        select *, getdate() as CreateDate, null
        from inserted

Your "audit" table has more columns than you're inserting (the deleted date); you need to either name all the columns, or insert a null.

Stylistically, naming the columns is better - it makes it clear what goes where, and avoid bugs when you add new columns.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top