I'm trying create a stored procedure that contains a merge clause and want save output clause to a table (logs.ProductTaxProfileLog).
In my search for information I do not see that the output clause is used within the stored procedure
CREATE PROCEDURE dbo.sp_ProductTaxProfiles
AS
BEGIN
MERGE dbo.ProductTaxProfiles AS prd
USING staging.ProductTaxProfiles AS stg
ON stg.ProductTaxProfileId = prd.ProductTaxProfileId
-- UPDATE
WHEN MATCHED AND (
prd.ProductTaxProfileDescription <> stg.ProductTaxProfileDescription
OR prd.ProductIvaConditionId <> stg.ProductIvaConditionId
OR prd.ProductIvaConditionDescription <> stg.ProductIvaConditionDescription
OR prd.ProductIibbConditionId <> stg.ProductIibbConditionId
OR prd.ProductIibbConditionDescription <> stg.ProductIibbConditionDescription
OR prd.ProductInternalTaxConditionId <> stg.ProductInternalTaxConditionId
OR prd.ProductInternalTaxConditionDescription <> stg.ProductInternalTaxConditionDescription
OR prd.McActive <> stg.McActive
) THEN
UPDATE
SET
prd.ProductTaxProfileDescription = stg.ProductTaxProfileDescription,
prd.ProductIvaConditionId = stg.ProductIvaConditionId,
prd.ProductIvaConditionDescription = stg.ProductIvaConditionDescription,
prd.ProductIibbConditionId = stg.ProductIibbConditionId,
prd.ProductIibbConditionDescription = stg.ProductIibbConditionDescription,
prd.ProductInternalTaxConditionId = stg.ProductInternalTaxConditionId,
prd.ProductInternalTaxConditionDescription = stg.ProductInternalTaxConditionDescription,
prd.McActive = 1,
prd.UpdatedDate = CURRENT_TIMESTAMP
-- INSERT
WHEN NOT MATCHED BY TARGET THEN
INSERT (
ProductTaxProfileId
,ProductTaxProfileDescription
,ProductIvaConditionId
,ProductIvaConditionDescription
,ProductIibbConditionId
,ProductIibbConditionDescription
,ProductInternalTaxConditionId
,ProductInternalTaxConditionDescription
,McActive
,CreatedDate
,UpdatedDate
,DeletedDate
)
VALUES (
stg.ProductTaxProfileId
,stg.ProductTaxProfileDescription
,stg.ProductIvaConditionId
,stg.ProductIvaConditionDescription
,stg.ProductIibbConditionId
,stg.ProductIibbConditionDescription
,stg.ProductInternalTaxConditionId
,stg.ProductInternalTaxConditionDescription
,1
,CURRENT_TIMESTAMP
,CURRENT_TIMESTAMP
,NULL
)
-- DELETE
WHEN NOT MATCHED BY SOURCE AND (prd.McActive <> 0) THEN
UPDATE
SET
prd.McActive = 0
,prd.DeletedDate = CURRENT_TIMESTAMP
OUTPUT
CASE
WHEN $action = 'UPDATE' AND inserted.McActive = 0 AND deleted.McActive = 1 THEN 'DELETE'
WHEN $action = 'UPDATE' AND inserted.McActive = 1 AND deleted.McActive = 1 THEN 'UPDATE'
WHEN $action = 'INSERT' AND inserted.McActive = 1 AND COALESCE(deleted.McActive,0) = 0 THEN 'INSERT'
WHEN $action = 'UPDATE' AND inserted.McActive = 1 AND COALESCE(deleted.McActive,0) = 0 THEN 'RE-INSERT'
END AS ActionType,
inserted.*,
deleted.*
INTO logs.ProductTaxProfileLog;
END
GO
But I got this error:
Can anyone help me? I know that merge clause needs a semicolon at the end, but I really don't know how fix this error.
Finally Find the answer.
I was working with dbeaver and for some reason got that error. But when you run it from SSMS (SQL Server Management Studio) it runs fine, and everything works.
In conclusion the problem was the IDE
Related
I have a trigger which adds a log entry into a table upon a field change in another table. it works when one row is changed but errors when multiple rows re changed. Anyone out there able to explain what I have to do to get my trigger working also for multi row updates?
Many thanks,
Derek
Declare #PropertyID uniqueidentifier
Set #PropertyID = (Select CONVERT(VARCHAR( 36 ), ISNULL(i.[PropertyPK], d.[PropertyPK]))
FROM
INSERTED i
FULL OUTER JOIN DELETED d ON ( d.[PropertyPK] = i.[PropertyPK] )
WHERE
( d.[strManagingOfficeName] <> i.[strManagingOfficeName] ) OR
( d.[strManagingOfficeName] IS NULL AND i.[strManagingOfficeName] IS NOT NULL ) OR
( i.[strManagingOfficeName] IS NULL AND d.[strManagingOfficeName] IS NOT NULL ))
Declare #CompanyID uniqueidentifier
Set #CompanyID = (Select CompanyFK From Property Where PropertyPK = #PropertyID)
--Deleted Old Ones
Delete From TDSAPILog Where ObjectFK = #PropertyID And strObject = 'Branch Change'
--Insert New Log
INSERT dbo.TDSAPILog(TDSAPILogPK, ObjectFK, strObject, strStatus, CompanyFK, dteDateLogged)
SELECT
NewID(),
#PropertyID,
'Branch Change',
'Active',
#CompanyID ,
GetDate()
This error occur when you return more than 1 value from a query and save in a variable or compare with a value in where clause.
In your example I think the error occur at this line
SET #CompanyID = (SELECT CompanyFK FROM Property WHERE PropertyPK = #PropertyID)
To resolve the reported error just put "TOP 1" in your query. Example is shown here:
SET #CompanyID = (SELECT TOP 1 CompanyFK FROM Property WHERE PropertyPK = #PropertyID)
Subquery returned more than 1 value error may occur at the following scenarios:
SET #YouVariable = (SELECT ColumnID FROM yourTable WHERE Identity = #SomeValue)
-- if the above query return more than 1 value the same error will be occurred
-- to resolve this problem just put "TOP 1" before ColumnID
SELECT *
FROM OtherTable
WHERE OtherIdentity = ((SELECT ColumnID FROM yourTable
WHERE Identity = #SomeValue))
-- if the above query return more than 1 value the same error will be occurred
-- to resolve this problem just replace "= with IN()". Example give below
SELECT *
FROM OtherTable
WHERE OtherIdentity IN ((SELECT ColumnID FROM yourTable
WHERE Identity = #SomeValue))
I am trying to update a linked table with this...
update openquery (LINKSERVERID, 'select tng_email from user_list where tng_id = 62873')
set tng_email = 'blah#blah.com';
... but I get the following error ...
OLE DB provider "MSDASQL" for linked server "LINKSERVERID" returned message "Key column information is insufficient or incorrect.
Too many rows were affected by update.".
FYI: tng_id is the primary key.
How do I fix?
I think you need to include the key in the select query, so try this:
update openquery(
LINKSERVERID, 'select tng_id, tng_email from user_list where tng_id = 62873'
) set tng_email = 'blah#blah.com';
I tried the answer above from jpw, but it didn't work for me.
I developed a trigger of which I also received the same error using the code below:
begin
if TRIGGER_NESTLEVEL() > 1
return
declare #JCid int = (select top 1 iJCMasterID from inserted)
begin
update L set uiJCTxCMLineNumber = NewLineNum
from (
select
rank() over (order by idJCTxLines) NewLineNum
, iJCMasterID
, uiJCTxCMLineNumber
, idJCTxLines
from _btblJCTxLines
where iJCMasterID = #JCid
) L
where iJCMasterID = #JCid
end
end
go
However, I resolved it by changing it to :
begin
if TRIGGER_NESTLEVEL() > 1
return
declare #JCid int = (select top 1 iJCMasterID from inserted)
begin
update L set uiJCTxCMLineNumber = NewLineNum
from (
select
rank() over (order by idJCTxLines) NewLineNum
, iJCMasterID
, uiJCTxCMLineNumber
, idJCTxLines
from _btblJCTxLines
where iJCMasterID = #JCid
) L
join inserted i on L.idJCTxLines = i.idJCTxLines
end
end
go
Hope this helps.
I solved this error by adding a unique index to the underlying table.
I've a table named 'VendorItemPricing' in my database. I'll insert/update data into this table periodically using Data Table, in other words bulk insert/update operation I'll perform.
Below is my stored procedure to perform this operation, and it works good.
Assume this is my table VendorItemPricing:
ItemPartNumber VendorName VendorPrice UpdatedDate ObsoleteItem IsLocked
Z0PD Apple 1177 2015-05-27 11:11:14.700 0 0
C1GM Apple 181.25 2015-05-27 11:11:14.700 0 1
Whenever I send a datatable to my stored procedure it'll check the condition.
Assume this is my input:
ItemPartNumber => Z0PD
VendorName => Apple
Now, it check with the condition.
tableVendor.ItemPartNumber = 'Z0PD' and tableVendor.VendorName = 'Apple' and tableVendor.IsLocked = 0
The first item will get updated since it satisfied the given condition.
Now assume this is my input:
ItemPartNumber => ZWEPD
VendorName => Apple
Now, it again check with the condition.
tableVendor.ItemPartNumber = 'ZWEPD' and tableVendor.VendorName = 'Apple' and tableVendor.IsLocked = 0
The new row will be inserted since the input data isn't matching with the condition. This's also great.
But in this type of input,
ItemPartNumber => C1GM
VendorName => Apple
When it check with the condition.
tableVendor.ItemPartNumber = 'C1GM' and tableVendor.VendorName = 'Apple' and tableVendor.IsLocked = 0
The condition is now false, and the query is inserting the new row. :(
It shouldn't insert the row, since there's a data with this part number. If Item with IsLocked = 1, it should not get neither updated nor inserted.
I hope I explained my situation clearly. Can anyone help me in fixing this error?
This is my stored procedure.
ALTER PROCEDURE [dbo].[WP_InsertUpdateVendorItemPrices]
#inputTable InsertUpdateVendorPrices READONLY
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO VendorItemPricing tableVendor
USING #inputTable tableTemp
ON tableVendor.ItemPartNumber = tableTemp.ItemPartNumber and tableVendor.VendorName = tableTemp.VendorName and tableVendor.IsLocked = 0
WHEN MATCHED THEN
UPDATE SET tableVendor.VendorPrice = tableTemp.VendorPrice, tableVendor.UpdatedDate = GETUTCDATE(), tableVendor.ObsoleteItem = 0
WHEN NOT MATCHED THEN
INSERT VALUES(tableTemp.ItemPartNumber, tableTemp.VendorName, tableTemp.VendorPrice, GETUTCDATE(), 0, 0);
END
Myself got an answer. Thanks everyone.
This is the latest updated working stored procedure.
ALTER PROCEDURE [dbo].[WP_InsertUpdateVendorItemPrices]
#inputTable InsertUpdateVendorPrices READONLY
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO VendorItemPricing tableVendor
USING #inputTable tableTemp
ON tableVendor.ItemPartNumber = tableTemp.ItemPartNumber and tableVendor.VendorName = tableTemp.VendorName
WHEN MATCHED THEN
UPDATE SET
tableVendor.VendorPrice = CASE WHEN tableVendor.IsLocked = 0 THEN tableTemp.VendorPrice ELSE tableVendor.VendorPrice END,
tableVendor.UpdatedDate = CASE WHEN tableVendor.IsLocked = 0 THEN GETUTCDATE() ELSE tableVendor.UpdatedDate END,
tableVendor.ObsoleteItem = CASE WHEN tableVendor.IsLocked = 0 THEN 0 ELSE tableVendor.ObsoleteItem END
WHEN NOT MATCHED THEN
INSERT VALUES(tableTemp.ItemPartNumber, tableTemp.[VendorName], tableTemp.[VendorPrice], GETUTCDATE(), 0, 0);
END
I need to insert multiple rows into another table using a trigger, but it only inserts the last record
I have checked some other posts in stackoverflow and didn't find an Answer,
This is my trigger
IF(#TNAEventID IN(1,2,3))
BEGIN
INSERT INTO [Biostar].Cen.WentOutLog (AutoID, nUserID, nOutDateTime,nOutTNAEvent ,nReaderID) values (#AutoID,#UseID, #DateTime,#TNAEventID, #ReaderID )
END
else IF(#TNAEventID=0)
BEGIN
UPDATE Cen.WentOutLog Set nINDateTime =#DateTime,nInTNAEvent = #TNAEventID Where AutoID = (Select top (1) AutoID from Cen.WentOutLog where nINDateTime is null AND nOutDateTime<#DateTime AND nUserID=#UseID order by nOutDateTime desc)
END
else
begin
....
end
Thanks in Advance.
You can try below code, Insert code is readily usable.
You might need to change the UPDATE statement as I do not know what is
your data:
INSERT INTO [Biostar].[Cen].[WentOutLog]
([AutoID], [nUserID], [nOutDateTime], [nOutTNAEvent], [nReaderID])
SELECT [AutoID], [nUserID], [nOutDateTime], [nOutTNAEvent], [nReaderID]
FROM INSERTED
WHERE TNAEventID IN (1, 2, 3)
UPDATE W
FROM [Cen].[WentOutLog]
SET W.[nINDateTime] = I.[DateTime],
W.[nInTNAEvent] = I.[TNAEventID]
INNER JOIN INSERTED I ON W.[AutoID] = I.[AutoID]
WHERE I.[TNAEventID] = 0
AND W.[nINDateTime] IS NULL
AND W.[nOutDateTime] < I.[DateTime]
AND W.[nUserID] = I.[UserID]
I have the following stored procedure:
ALTER PROCEDURE [dbo].[sp_Detail]
#ReceiptNumber int
AS
BEGIN
SET NOCOUNT ON;
WITH invoiceT AS
(SELECT
fs_transaksie.enti AS Entity,
fs_transaksie.rek AS Account,
fs_transaksie.trans_tipe AS TransactionType,
fs_transaksie.verwysnr AS ReferenceNumber
FROM mf_history.dbo.fs_transaksie
WHERE ( fs_transaksie.verwysnr = #ReceiptNumber ) AND (fs_transaksie.trans_tipe = 3))
, transactionT as
(SELECT
fs_kwitansie.kwitansienr AS InvoiceNumber,
fs_kwitansie.ktkaart_nr AS CreditCardNumber,
fs_kwitansie.ktkaart_bank AS CCBank,
fs_kwitansie.ktkaart_bedrag AS CCAmount
FROM mf_history.dbo.fs_kwitansie
WHERE ( fs_kwitansie.kwitansienr = #ReceiptNumber )
)
select *
from invoiceT
full outer join transactionT on invoiceT.ReferenceNumber = transactionT.InvoiceNumber
END
If the fs_transaksie.trans_tipe field = 3 and fs_transaksie.rek = 5205 then an error message needs to be displayed to the user. He may NOT view the data
If you can just not display the data, rather than raising an error then changing your WHERE clause to:
WHERE ( fs_transaksie.verwysnr = #ReceiptNumber ) AND (fs_transaksie.trans_tipe = 3)
And (fs_transaksie.rek != 5205)
should exclude it - you are already filtering it to just be trans_tipe = 3 so adding the And (fs_transaksie.rek != 5205) will exclude any where the results are 3 and 5205 respectively.