Update a table with scope identity from new inserted row - sql-server

I have a table in which I need to update one column with ticketnumbers.
These ticketnumbers are created in another table where it is an identity field.
This code doesn't work. Why?
UPDATE sheet10
SET [TicketNummer] = (INSERT INTO ticketnummers (AangemaaktOp, aangemaaktdoor,verwijderd,afgewezen) VALUES ('2014-01-20 15:00:00',100,0,0) SELECT SCOPE_IDENTITY() )
where isnumeric([TicketNummer]) = 0
What am I doing wrong?
rg.
Eric

Composable DML should let you INSERT only if the UPDATE has a row matching
However...
how do you correlate rows?
What happens for concurrent inserts?
What if multiple rows have no TicketNummer value in sheet10
and many other questions
In summary, this is possible even if I'd never actually do it given the design questions
UPDATE
sheet10
SET
TicketNummer = (
SELECT
*
FROM
(
INSERT INTO ticketnummers (AangemaaktOp, aangemaaktdoor,verwijderd,afgewezen)
OUTPUT INSERTED.IDColumn
VALUES ('2014-01-20 15:00:00', 100, 0, 0)
) X
)
WHERE
ISNULL(TicketNummer, 0) = 0;

You cannot use INSERT in this way. It has to be statement on its own.
Basically you have to perform this operation in 2 steps:
INSERT INTO ticketnummers (AangemaaktOp, aangemaaktdoor,verwijderd,afgewezen) VALUES ('2014-01-20 15:00:00',100,0,0);
UPDATE sheet10
SET [TicketNummer] = SCOPE_IDENTITY()
where ISNULL([TicketNummer], 0) = 0

Related

How to query values when a column has N value

So I have the following table:
And I'm trying to write a Query where I can send the code BR_BN as a variable in my WHERE clause
and if I get BR_BN then I want to retrieve the records with this code AND the records with the Code_FS RB02. On the other side when I get the value AB_CP, I want to include the recordes with the Code_FS RB01.
Here's the Query I've tried so far:
DECLARE #Code_OB VARCHAR(20) = 'BR_BN'
SELECT * FROM Dummy_AV
WHERE FK = 2
OR
(#Code_OB = 'BR_BN' AND Code_FS = 'RB02' AND Code_FS = #Code_OB)
But it doesn't work, it retrieves all the records regardless of the FK, and/or the #Code_FS.
How can I achieve this?
Thanks for the help.
You don't note the FK = 2 being needed, yet you have it in front of an OR in the WHERE clause. I think this is what you're after, if it isn't exactly what you're aiming for hopefully it gets you on the right track. For future questions, always helpful to paste your sample data as data instead of an image.
DECLARE #Code_OB VARCHAR(20) = 'BR_BN'
SELECT * FROM Dummy_AV
WHERE FK = 2 -- you will get all rows where this is true
OR
((#Code_OB = Code_OB AND Code_FS = 'RB02') OR (Code_OB = 'AB_CP' AND Code_FS = 'RB01')) -- you will get all rows where one of these is true

SQL Server trigger for changing value of column of inserted row according to delta from other table after insert?

I have 2 tables in my SQL Server database, for example [Camera] and [CameraData]. How to write a trigger which will change value in [CameraData] after row is inserted into [CameraData] due to delta in [Camera].
For example we have 2 cameras in [Camera]:
Camera 1 with {id} = 1 and {delta} = null
Camera 2 with {id} = 2 and {delta} = 3
So when we have automated insert into table [CameraData], f.e. :
Id_camera = 2, angle = 30, Changed = null
In that case we need to check either we have delta in [Camera] on camera 2 and if that's true we need to modify insert to:
Id_camera = 2, angle = 33 (angle + Camera.Delta), Changed = True
Update 1
According to comment [3] is the column in table [CameraData] where angle is placed
CREATE TRIGGER Delta_Angle
ON CameraData
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
UPDATE CameraData
SET DeltaFlag = 1, [3] = inserted.[3] + i.DeltaAngle
FROM CameraData h
INNER JOIN Camera i ON h.ID_Camera = i.ID_Camera
WHERE i.DeltaAngle != ''
END
This is very much a stab in the dark, as your sample SQL isn't at all representative of the data your describe in your question, however, maybe something like:
CREATE TRIGGER Delta_Angle ON CameraData
AFTER INSERT AS
BEGIN
SET NOCOUNT ON;
UPDATE C
SET Angle = C.Angle + i.delta
FROM Camera
JOIN inserted i ON C.CameraID = i.CameraID;
END
Notice that I refer to inserted; your trigger wasn't. Also, I'm not sure about your clause i.DeltaAngle != ''. Considering that DeltaAngle appears to be an int, it can never have a value of '' (however, '' would be implicitly converted to the value 0).
If this doesn't help, I (again) suggest you read Sean's link and update your post accordingly.

Trigger avoid inserting duplicates

I have created a trigger when a value is inserted to the main table dbo.MVF_Transport_Register, it updtes the dbo.MVF_Transport_Acc table with that record. Also when a value is changed on the main table dbo.MVF_Transport_Register it updates the particular field value accordingly on the other dbo.MVF_Transport_Acc.
Problem I have is: my trigger inserts duplicate records into the dbo.MVF_Transport_Acc table.
How can I amend this trigger so it checks dbo.MVF_Transport_Acc to see if the record exsists before inserting the record. If the record exists, it shouldn't insert duplicate records.
Can some one please check my trigger an advice how to sort this thanks in advance big help
ALTER TRIGGER [dbo].[UpdateTransport]
ON [dbo].[MVF_Transport_Register]
AFTER UPDATE
AS
BEGIN
UPDATE c
SET c.Record_Status = i.Record_status
FROM MVF_SYSTEMS.dbo.MVF_Transport_Acc AS c
INNER JOIN inserted AS i ON c.Order_No = i.Order_No
AND c.Record_Status <> i.Record_Status
WHERE i.Record_Status IN ('CONFIRMED', 'AMENDED')
AND i.Price > 0;
IF ##ROWCOUNT = 0
BEGIN
INSERT INTO MVF_SYSTEMS.dbo.MVF_Transport_Acc ([Order_No], [Record_Status], [Notes], [Transport_Supplier],
[Surcharge], [Vendor_No], [Pallets], [Amend_Pallets],[Price],
[Input_Date], [Amend_Price], [Transport_Invoice_No],[Transport_Job_No],
[Amend_Date], [Report_Price], [Return_Price], [Report_Date])
SELECT
i.[Order_No], i.[Record_Status], i.[Notes], i.[Transport_Supplier],
i.[Surcharge], i.[Vendor_No], i.[Pallets], i.[Amend_Pallets], i.[Price],
i.[Input_Date], i.[Amend_Price], i.[Transport_Invoice_No], i.[Transport_Job_No],
i.[Amend_Date], i.[Report_Price], i.[Return_Price], i.[Report_Date]
FROM
inserted AS i
WHERE
i.Record_Status IN ('CONFIRMED', 'AMENDED')
AND i.Price > 0;
END
END

Need help understand this example about SQL Server rowversion?

Before reading this example, I can understand rowversion myself that it reflects the last updated timestamp on a record. I think about its usage like this: First after reading a record, the rowversion column value should be achieved. Then before updating that record, the locally stored rowversion value should be checked against the current rowversion value fetched from database (at the time before updating), if they are not equal then it means there has been some update from another user and the current app should handle that concurrency situation with its own strategy.
However I think the following example either over-complicates the problem or may be even wrong or poorly explained (so lead to confusion):
CREATE TABLE MyTest (myKey int PRIMARY KEY
,myValue int, RV rowversion);
GO
INSERT INTO MyTest (myKey, myValue) VALUES (1, 0);
GO
INSERT INTO MyTest (myKey, myValue) VALUES (2, 0);
GO
DECLARE #t TABLE (myKey int);
UPDATE MyTest
SET myValue = 2 OUTPUT inserted.myKey INTO #t(myKey)
WHERE myKey = 1 AND RV = myValue;
IF (SELECT COUNT(*) FROM #t) = 0
BEGIN
RAISERROR ('error changing row with myKey = %d'
,16 -- Severity.
,1 -- State
,1) -- myKey that was changed
END;
I notice myValue here, it's set to 2 and also used in the WHERE clause to check against the RV column. As my understand the rowversion column is obviously RV but then it explains this:
myValue is the rowversion column value for the row that indicates the last time that you read the row. This value must be replaced by the actual rowversion value
I didn't think myValue has anything to do with rowversion here, it should just be considered as user data. So with such explanation, the MyTest table has 2 rowversion columns? while myValue is obviously declared as int?
A possibility I can think of is myValue in WHERE condition is understood differently (meaning it was not the myValue in the SET clause), it may be just a placeholder such as for the read value of RV at the time reading the record before. Only that possibility makes sense to me.
So as I understand the example should be like this:
SET myValue = 2 OUTPUT inserted.myKey INTO #t(myKey)
WHERE myKey = 1 AND RV = rowVersionValueFromTheLastTimeReading
I've heard of timestamp before but rowversion is fairly new to me and once I tried finding more about it, I found this example making me so confused. What is your idea about this? Or I simply don't understand some of the mysterious usages of rowversion? Thanks.
The example in the Books Online is incorrect. I see that was called out in the community comments for the topic.
The code below shows how one might use rowversion to implement optimistic concurrency. This method is often employed when data are presented to the user for update and then modified.
DECLARE
#MyKey int = 1
,#NewMyValue int = 1
,#OriginalMyValue int
,#OriginalRV rowversion
--get original data, including rowversion
SELECT
#OriginalMyValue = myValue
, #OriginalRV = RV
FROM dbo.MyTest
WHERE myKey = 1;
--check original rowversion value when updating row
UPDATE dbo.MyTest
SET myValue = #NewMyValue
WHERE
myKey = 1
AND RV = #OriginalRV;
--optimistic concurrency violation
IF ##ROWCOUNT = 0
RAISEERROR ('Data was updated or deleted by another user.', 16, 1);
Alternatively, the original data value(s) can be checked instead of rowversion. However, this gets unwieldy if you have a lot of columns and need to check for NULL values. That's where rowversion is handy.
--check original rowversion value when updating row
UPDATE dbo.MyTest
SET myValue = #NewMyValue
WHERE
myKey = 1
AND (myValue = #OriginalMyValue
OR (myValue IS NULL AND #OriginalMyValue IS NULL));
Timestamp is a database synonym for rowversion. You don't need to understand any of the mysteries, you should just not use it. It is deprecated and will be removed in the future.
https://msdn.microsoft.com/en-us/library/ms182776.aspx

Oracle Triggers Update at Another Table

I am trying to create a trigger in Oracle. I know sql but i have never created trigger before. I have this code:
create or replace trigger "PASSENGER_BOOKING_T1"
AFTER
insert on "PASSENGER_BOOKING"
for each row
begin
IF (:NEW.CLASS_TYPE == 'ECO')
SELECT F.AVL_SEATS_ECOCLASS,F.FLIGHT_ID INTO SEAT, FLIGHT_INFO
FROM BOOKING B, JOURNEY_FLIGHT J, FLIGHT F
WHERE B.JOURNEY_ID = J.JOURNEY_ID and F.FLIGHT_ID = J.FLIGHT_ID;
UPDATE FLIGHT
SET AVL_SEATS_ECOCLASS = (SEAT-1)
WHERE FLIGHT_ID = FLIGHT_INFO;
END IF;
end;​
This trigger fires when there is an insert in Passenger_Booking table. And seating capacity is reduced by one (which is at different table).
Select query should be alright but there is something wrong in somewhere.
Could anyone suggest anything?
I changed the body part to this but still having issues:
UPDATE FLIGHT
SET AVL_SEATS_ECOCLASS =
(SELECT F.AVL_SEATS_ECOCLASS FROM BOOKING B, JOURNEY_FLIGHT J, FLIGHT F WHERE B.JOURNEY_ID = J.JOURNEY_ID and F.FLIGHT_ID = J.FLIGHT_ID;
);
An IF statement needs a THEN
In PL/SQL, you use an = to test for equality, not ==
You need to declare the variables that you are selecting into
When I do those three things, I get something like this
create or replace trigger PASSENGER_BOOKING_T1
AFTER insert on PASSENGER_BOOKING
for each row
declare
l_seat flight.seat%type;
l_flight_id flight.flight_id%type;
begin
IF (:NEW.CLASS_TYPE = 'ECO')
THEN
SELECT F.AVL_SEATS_ECOCLASS,F.FLIGHT_ID
INTO l_seat, l_flight_id
FROM BOOKING B,
JOURNEY_FLIGHT J,
FLIGHT F
WHERE B.JOURNEY_ID = J.JOURNEY_ID
and F.FLIGHT_ID = J.FLIGHT_ID;
UPDATE FLIGHT
SET AVL_SEATS_ECOCLASS = (l_seat-1)
WHERE FLIGHT_ID = l_flight_id;
END IF;
end;​
Beyond those syntax errors, I would be shocked if the SELECT INTO statement was correct. A SELECT INTO must return exactly 1 row. Your query should almost certainly return multiple rows since there are no predicates that would restrict the query to a particular flight or a particular booking. Presumably, you want to join to one or more columns in the PASSENGER_BOOKING table.
Additionally, if this is something other than a homework assignment, make sure you understand that this sort of trigger does not work correctly in a multi-user environment.
just a wild guess
edit as Justin pointed out (thanks Justin) equality check
create or replace trigger "PASSENGER_BOOKING_T1"
AFTER
insert on "PASSENGER_BOOKING"
for each row
declare
v_flight_id FLIGHT.FLIGHT_ID%TYPE;
begin
IF (:NEW.CLASS_TYPE = 'ECO') THEN
SELECT F.ID into v_flight_id
FROM BOOKING B, JOURNEY_FLIGHT J, FLIGHT F
WHERE B.ID = :NEW.BOOKING_ID -- note that I've made this up
AND B.JOURNEY_ID = J.JOURNEY_ID AND F.FLIGHT_ID = J.FLIGHT_ID;
UPDATE FLIGHT
SET AVL_SEATS_ECOCLASS = (SEAT-1)
WHERE ID = v_flight_id;
END IF;
end;​

Resources