SQL Server export image to hardisc by iterating through fieldnames - sql

We receive 10 images in varchar format through a mobile device app which are stored in one record of a table. The fields where the images are imported are named ImportPictureData, ImportPictureData2,...
[ID] [int] IDENTITY(1,1) NOT NULL,
[Projectnumber] [varchar](20) NULL,
[DeviceID] [nchar](20) NULL,
[Sendtime] [datetime] NULL,
[DeviceName] [nchar](30) NULL,
[ImportPictureData] [varchar](max) NULL,
[PictureData] [varbinary](max) NULL,
[ImportPictureData2] [varchar](max) NULL,
[PictureData2] [varbinary](max) NULL,
[ImportPictureData3] [varchar](max) NULL,
[PictureData3] [varbinary](max) NULL,
[ImportPictureData4] [varchar](max) NULL,
[PictureData4] [varbinary](max) NULL,
[ImportPictureData5] [varchar](max) NULL,
[PictureData5] [varbinary](max) NULL,
[ImportPictureData6] [varchar](max) NULL,
[PictureData6] [varbinary](max) NULL,
[ImportPictureData7] [varchar](max) NULL,
[PictureData7] [varbinary](max) NULL,
[ImportPictureData8] [varchar](max) NULL,
[PictureData8] [varbinary](max) NULL,
[ImportPictureData9] [varchar](max) NULL,
[PictureData9] [varbinary](max) NULL,
more of the importfields could be added.
To make the export flexible, I read the fieldnames in a table variable and try to create a dynamic SQL for the loop through the fields.
The SQL-string looks good where I create the string and print it(!) and then I try to assign the string to the variable which should recieve the image data:
set #sqlDynamicString='(Select Cast('''' AS XML).value(''xs:base64Binary(sql:column("'+ #PictureDateFieldName + '"))'', ''VARBINARY(MAX)'') FROM ScanIT_tblProjektbilder Where ID='''+ #PicID +''')'
creates this string:
(Select Cast('' AS XML).value('xs:base64Binary(sql:column("ImportPictureData"))', 'VARBINARY(MAX)') FROM ScanIT_tblProjektbilder Where ID='105')
DECLARE #ImageData VARBINARY(max);
select #ImageData = (Select Cast('' AS XML).value('xs:base64Binary(sql:column("ImportPictureData"))', 'VARBINARY(MAX)') FROM ScanIT_tblProjektbilder Where ID='105')
When I assign this string as a hardcopy to the variable #ImageData I do not get any error, if I am going to assign the variable #sqlDynamicString to the variable #ImageData like
select #ImageData = #sqlDynamicString
I get an
error 257: Implicit conversion from datatype 'VARCHAR' to 'VARBINARY(MAX)' is not allowed. Use CONVERT-Function
what is going wrong here??
Even using convert iso cast I get the same error.
Thanks

Execute the code in #sqlDynamicString,store the result in a temp table and then assign to your varbinary variable.
create table #temp
(
imageData varbinary(max)
)
insert into #temp
exec #sqlDynamicString
select #ImageData=(select imageData from #temp)

Related

Stored procedure throws an error while getting data from two table using UNION

I have two tables which are shown in this screenshot:
I am writing a stored procedure which will return data from both tables:
ALTER PROCEDURE [dbo].[GetInventoryDetails]
#MaterialId INT
AS
BEGIN
SELECT
tms.Material_ID AS MaterialId,
tmm.Name As MaterialName,
CONVERT(varchar,Quantity) AS AddedQuantity,
UtilizedQuantity ='-',
tcl.LedgerName AS SupplierName,
UsedFor = '-',
tmm.CurrentStock,
tmm.OpeningStock,
CONVERT(DATETIME,CONVERT(VARCHAR(100), tms.Material_Date, 112)) AS MaterialDate,
tms.Narration AS Narration
FROM
tblMaterialSheet tms
JOIN
tblMaterialMaster tmm ON tmm.Material_ID = tms.Material_ID
JOIN
tblCompanyLedger tcl ON tcl.Pk_LedgerId = tms.Ledger_ID
WHERE
tms.Material_ID = #MaterialId
AND tms.isActive = 1
UNION
SELECT
tmu.Material_ID AS MaterialId,
tmm.Name As MaterialName,
AddedQuantity = '-',
CONVERT(varchar,Utilized_Quantity) AS UtilizedQuantity,
CONVERT(DATETIME,CONVERT(VARCHAR(100), Utilization_Date, 112)) AS MaterialDate,
SupplierName = '-',
tbst.Name AS UsedFor,
tmm.CurrentStock,
tmm.OpeningStock,
tmu.Narration As Narration
FROM
tblMaterialUtilization tmu
JOIN
tblMaterialMaster tmm ON tmm.Material_ID = tmu.Material_ID
JOIN
tblBuildingSubTask tbst ON tbst.BuildingSubTask_ID = tmu.BuildingSubTask_ID
WHERE
tmu.Material_ID = #MaterialId
AND tmu.isActive = 1
END
When I call the stored procedure, it throws an error:
Conversion failed when converting date and/or time from character string.
Table structure: tblmaterialsheet
CREATE TABLE [dbo].[tblMaterialSheet]
(
[MaterialSheet_ID] [int] IDENTITY(1,1) NOT NULL,
[Company_ID] [int] NOT NULL,
[User_ID] [int] NOT NULL,
[BuildingSubTask_ID] [int] NOT NULL,
[Material_Date] [datetime] NOT NULL,
[Material_ID] [int] NOT NULL,
[Unit_ID] [int] NOT NULL,
[Quantity] [decimal](10, 2) NOT NULL,
[Size_ID] [int] NULL,
[Height] [decimal](6, 2) NULL,
[Width] [decimal](6, 2) NULL,
[Rate_Per_Unit] [money] NULL,
[Paid_Amount] [money] NULL,
[Total_Amount] [money] NULL,
[Vehical_No] [varchar](50) NULL,
[Ledger_ID] [int] NULL,
[Narration] [varchar](max) NULL,
[Challan_No] [int] NULL,
[Bill_ID] [int] NULL,
[isBilled] [bit] NOT NULL,
[Approval] [varchar](50) NULL,
[Approval_ModifiedDate] [datetime] NULL,
[UploadImage] [image] NULL,
[isActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL
)
Table structure : tblMaterialUtilization
CREATE TABLE [dbo].[tblMaterialUtilization]
(
[MaterialUtilization_ID] [int] IDENTITY(1,1) NOT NULL,
[Company_ID] [int] NOT NULL,
[User_ID] [int] NOT NULL,
[BuildingSubTask_ID] [int] NOT NULL,
[Material_ID] [int] NOT NULL,
[Utilization_Date] [datetime] NOT NULL,
[Utilized_Quantity] [decimal](10, 2) NOT NULL,
[Narration] [varchar](max) NOT NULL,
[IsActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL
)
Table structure : tblMaterialMaster
CREATE TABLE [dbo].[tblMaterialMaster]
(
[Material_ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](100) NOT NULL,
[Unit_ID] [int] NOT NULL,
[IsActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
[OpeningStock] [numeric](18, 0) NULL,
[PurchaseLedger] [numeric](18, 0) NULL,
[CurrentStock] [numeric](18, 0) NULL
)
Table structure : tblBuildingSubTask
CREATE TABLE [dbo].[tblBuildingSubTask]
(
[BuildingSubTask_ID] [int] IDENTITY(1,1) NOT NULL,
[BuildingTask_ID] [int] NOT NULL,
[Name] [varchar](200) NOT NULL,
[Narration] [varchar](max) NULL,
[StartDate] [datetime] NULL,
[TargetCompletionDate] [datetime] NULL,
[ActualCompletionDate] [datetime] NULL,
[IsActive] [bit] NOT NULL,
[CreatedBy] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL
)
How to solve this error?
TRY THIS NOW: The order of the column were not in the same order so it was getting the different datatype values for the same column. Datatype and Order is most important in the UNION
ALTER PROCEDURE [dbo].[GetInventoryDetails]
#MaterialId int
AS
BEGIN
SELECT
tms.Material_ID AS MaterialId,
tmm.Name As MaterialName,
CONVERT(varchar,Quantity) AS AddedQuantity,
UtilizedQuantity ='-',
tcl.LedgerName AS SupplierName,
UsedFor='-',
tmm.CurrentStock,
tmm.OpeningStock,
CONVERT(DATETIME,CONVERT(VARCHAR(100), tms.Material_Date, 112)) AS MaterialDate,
tms.Narration As Narration
FROM
tblMaterialSheet tms
JOIN tblMaterialMaster tmm on tmm.Material_ID = tms.Material_ID
JOIN tblCompanyLedger tcl on tcl.Pk_LedgerId = tms.Ledger_ID
WHERE
tms.Material_ID = #MaterialId
AND
tms.isActive = 1
UNION
SELECT
tmu.Material_ID AS MaterialId,
tmm.Name As MaterialName,
AddedQuantity = '-',
CONVERT(varchar,Utilized_Quantity) AS UtilizedQuantity,
SupplierName = '-', --Moved up
tbst.Name AS UsedFor, --Moved up
tmm.CurrentStock, --Moved up
tmm.OpeningStock, --Moved up
CONVERT(DATETIME,CONVERT(VARCHAR(100), Utilization_Date, 112)) AS MaterialDate,
tmu.Narration As Narration
FROM
tblMaterialUtilization tmu
JOIN tblMaterialMaster tmm on tmm.Material_ID = tmu.Material_ID
JOIN tblBuildingSubTask tbst on tbst.BuildingSubTask_ID = tmu.BuildingSubTask_ID
WHERE
tmu.Material_ID = #MaterialId
AND
tmu.isActive = 1
END
The troubleshooting direction I'd take:
Look at your SQL. You're looking for anything that might be converting something of non-date type to date type. Your error probably means there's data somewhere you're converting to date that can't be converted. Be aware that this can include comparisons or functions that output a date.
Looking at your example, without knowing that actual data types, the only place I can see this happening is the explicit CONVERT functions on tms.Material_Date and Utilization_Date. I'd quickly comment these out and run each of the halves of the UNION separately. If they work, I could uncomment one or other until I figure out which field is causing the error. If they work independently but not unioned, I know that it's the after-union fields getting converted to date because the pre-union field is date.
Say it's the first half, before the union. I'd run:
SELECT * As Narration
FROM
tblMaterialSheet tms
JOIN tblMaterialMaster tmm on tmm.Material_ID = tms.Material_ID
JOIN tblCompanyLedger tcl on tcl.Pk_LedgerId = tms.Ledger_ID
WHERE
tms.Material_ID = #MaterialId
AND
tms.isActive = 1
AND
ISDATE(tms.Material_Date) = 0
You might need to work outwards in your converting to see where it falls over, e.g.,
AND
ISDATE(CONVERT(VARCHAR(100), tms.Material_Date, 112))
Then you should have a good idea about the problem.
Incidentally,
CONVERT(DATETIME,CONVERT(VARCHAR(100), Utilization_Date, 112))
looks very odd - what are you trying to achieve here by converting a date to varchar and back?
When you write a UNION or UNION ALL, You should make sure the following
No of Columns should be Same for Each Select Should Be same
Data Type of Column coming on the same position of each select Should be same
Suppose I have a column with character datatype for the first select and I'm trying to union it with a DateTime datatype, then I will get the error
SELECT 'ABCD'
UNION ALL
SELECT GETDATE()
This will throw the error
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
because the datatypes do not match.
And this will cause another error:
SELECT 'ABCD',GETDATE()
UNION ALL
SELECT GETDATE()
Like this:
Msg 205, Level 16, State 1, Line 1
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
because the number of columns does not match.
So make sure that the datatypes match for each column in your UNION and if they does not match, try Cast or Convert

How to update my table where updated columns names stored in another table in SQL Server

I have table User with n columns that stores user information in it.
I have another table User_Edit_Changes that I use to temporarily store changes to table User in it so that after admin confirmation I update the actual table User with new values.
In table User_Edit_Changes, I stored which user column requested for update and what is new value for that. How to write a dynamic query to get just changed value columns and new value from User_Edit_Changes and update the User table?
here is my sample create table command ,
teacher stores infos,
Tbl_ProfessorRequest stores edit change request,
Tbl_ProfessorEditInfoFields stores which fileds teacher request to edit
CREATE TABLE [dbo].[Teacher](
[code_ostad] [numeric](18, 0) NOT NULL,
[name] [varchar](30) NULL,
[family] [varchar](40) NOT NULL,
[namep] [varchar](30) NULL,
[idmadrak] [numeric](18, 0) NULL,
[namemadrak] [varchar](50) NULL,
[idresh] [numeric](18, 0) NULL,
[nameresh] [varchar](50) NULL,
[martabeh] [numeric](18, 0) NULL,
[namemartabeh] [varchar](30) NULL,
[nahveh_hamk] [numeric](18, 0) NULL,
CREATE TABLE [Request].[Tbl_ProfessorRequest](
[ProfessorRequestID] [int] IDENTITY(1,1) NOT NULL,
[Code_Ostad] [int] NULL,
[RequestTypeID] [bigint] NULL,
[RequestLogID] [bigint] NULL,
[CreateDate] [nvarchar](10) NULL,
[Note] [nvarchar](1000) NULL,
[term] [nvarchar](8) NULL,
[ProfessorMessage] [nvarchar](1000) NULL,
[Erae_Be] [nvarchar](100) NULL,
[ChangeSet] [int] NULL,
[isdeleted] [bit] NOT NULL,
[ScanImageUrl] [nvarchar](300) NULL,
CREATE TABLE [Request].[Tbl_ProfessorEditInfoFields](
[Id] [int] IDENTITY(1,1) NOT NULL,
[code_ostad] [int] NOT NULL,
[teacher_Column_Name] [nvarchar](200) NULL,
[OldValue] [nvarchar](200) NULL,
[NewValue] [nvarchar](200) NULL,
[State] [int] NOT NULL,
[ProfessorRequestID] [int] NOT NULL,
I'd say you have 3 options:
Handle the logic of updates outside the database, in what ever your application is built with. That's most likely the easiest way, since this kind of dynamic handling is not what databases are good at.
Build a dynamic SQL clause based on the contents of User_Edit_Changes. Loop through the changes in the table, construct an update statement into a variable and use sp_executesql to execute it. With cursor the code should be something like this:
set #params = N'#NewValue varchar(100)'
fetch next from yourcursor into #FieldName, #NewValue
while ##FETCH_STATUS = 0 begin
set #sql = 'update User set ' + #FieldName + ' = #NewValue'
exec sp_executesql #sql, #params, #NewValue = #NewValue
fetch next from yourcursor into #FieldName, #NewValue
end
Create static SQL statements for updating each of the columns. You can build something like this:
update U
set U.UserName = C.NewValue
from
User U
join User_Edit_Changes C on U.UserId = C.UserId
where
C.FieldName = 'UserName'
For this you of course need to have similar statements for each of your columns. You could build one massive update query with pivot or max+case, but handling the old and new values gets pretty complex.

insert data in fixed length column sql server

I am trying to insert data in fixed length column but I am getting an error.
The table looks like this:
CREATE TABLE [dbo].[zam_pcinfo](
[Id] [decimal] identity NOT NULL,
[employe_name] [nvarchar](50) NOT NULL,
[location_id] [decimal] NOT NULL,
[department_id] [decimal] NOT NULL,
[computer_name] [nvarchar](25) NOT NULL,
[user_name] [nvarchar](25) NOT NULL,
[teamviewer_id] [nvarchar](25) NULL check (DATALENGTH(teamviewer_id) = 9),
[lan_ip] [nvarchar](20) NULL,
[policy] [nvarchar](25) NOT NULL,
[os] [nvarchar](25) NOT NULL,
[pctype] [nvarchar](25) NOT NULL,
[note] [nvarchar](50) NULL,
[password] [nvarchar](25) NOT NULL,
[tmngr] [bit] NOT NULL,
[type_user] [nvarchar] (25) Not null,
[w-internal-mac-address] [nvarchar](50) null)
I am using DATALENGTH function for teamviewer_id column, and when I am trying to insert data into this column it shows this error:
insert statement is conflict with check constraint "nameoftheconstraint" the conflict occurred in database "nameofdatabase", table "nameoftable" column teamviewer_id
Can you help me in that? And is the check constraint is right in this situation?
i use Len instead and its work , thank you

How to call procedure for each row?

I have a Microsoft SQL Server R2 2008. And i see it first time in my life.
I have sql procedure:
DECLARE #RC int
DECLARE #Id uniqueidentifier
DECLARE #Segment_ID uniqueidentifier
DECLARE #SDate datetime
DECLARE #EDate datetime
DECLARE #withBig bit
DECLARE #withKm bit
DECLARE #withGeo bit
DECLARE #withDescr bit
-- TODO: задайте здесь значения параметров.
EXECUTE #RC = [Request_BusStation]
#Id
,#Segment_ID
,#SDate
,#EDate
,#withBig
,#withKm
,#withGeo
,#withDescr
GO
How i understand its just calling of procedure not thetself. But procedure too bit to copy it here.
AND have a table:
CREATE TABLE [BusStation](
[Id] [uniqueidentifier] NOT NULL,
[Segment_ID] [uniqueidentifier] NOT NULL,
[Dist] [decimal](18, 4) NOT NULL,
[Kod_Spr012] [smallint] NOT NULL,
[Square] [decimal](18, 6) NULL,
[OperationStartDate] [date] NULL,
[BallanceCost] [decimal](18, 6) NULL,
[DepreciatedCost] [decimal](18, 6) NULL,
[ChargesNorm] [decimal](18, 6) NULL,
[DocumentName] [varchar](100) NULL,
[DocumentNum] [varchar](100) NULL,
[DocumentDate] [date] NULL,
[Authority] [varchar](100) NULL,
[Kod_Spr091] [smallint] NOT NULL,
[HasWaysideStop] [bit] NOT NULL,
[HasLanding] [bit] NOT NULL,
[HasSpeedTransitArea] [bit] NOT NULL,
[LenSpeedTransitArea] [decimal](18, 6) NULL,
[YearBuilt] [smallint] NULL,
[YearMajorOverhaul] [smallint] NULL,
[Kod_Spr019] [smallint] NOT NULL,
[TechCond] [varbinary](max) NULL,
[LandCont] [varbinary](max) NULL,
[LandContDate] [date] NULL,
[LandContStartDate] [date] NULL,
[LandContEndDate] [date] NULL,
[Kod_Spr120] [smallint] NULL,
[E_Date_Begin] [datetime] NOT NULL,
[E_Date_End] [datetime] NULL,
[E_Date_Stop] [datetime] NULL,
Now i want to call this procedure for each row of table.
Its possible?
Yes, you can use a cursor that selects all the rows in the table and iteratively calls the stored procedure.
I would suggest that you may have a design issue before going down that route though. If the stored procedure needs to be called for every row in the table, you may be able to write a stored procedure that simply does what your current sp does to all the rows instead of a single row operation.
You have not provided what the sp is doing so I can only speculate here.
As mentioned in my comment, the only way I would know how to do that is using a CURSOR. Here is some sample code (untested of course):
DECLARE #ID INT
DECLARE #Segment_ID uniqueidentifier
DECLARE #getAccountID CURSOR
SET #BusStationCursor = CURSOR FOR
SELECT Id, Segment_ID --(etc: all the fields you need)
FROM BusStation
OPEN #BusStationCursor
FETCH NEXT FROM #BusStationCursor INTO #ID, #Segment_ID
WHILE ##FETCH_STATUS = 0
BEGIN
--CALL YOUR SP HERE
PRINT #ID
PRINT #Segment_ID
FETCH NEXT FROM #BusStationCursor INTO #ID, #Segment_ID
END
CLOSE #BusStationCursor
DEALLOCATE #BusStationCursor
This should help as well:
http://msdn.microsoft.com/en-us/library/ms180169.aspx
Good luck.

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

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!
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
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.