Update multiple tables with one query - sql-server

Record to update
select *
from Event_Measurable em
join Observation_Measurable om on em.Event_GUID = om.Event_GUID
where observation_guid in (8786975, 285886, 85976, 786976)
Update these records as follows:
set observation_value_text = '.',
observation_value_numeric = NULL,
om.status = 'D',
em.status = 'D',
I need help to update and set this values from the results of the query above. Can any help me. I have tried to update the table but it failed.

Try this:
update X set
observation_value_text = '.'
, observation_value_numeric = NULL
, om.status = 'D'
, em.status = 'D'
from
(
select
*
from Event_Measurable em
join Observation_Measurable om on em.Event_GUID = om.Event_GUID
where observation_guid in (8786975, 285886, 85976, 786976)
) X
Let me know if it works?

Your set list references multiple tables: that is invalid as only one table can be updated with one statement. You need to run 2 update statements so you either repeat the join in the second update or first put the result in a temp table and join that to the actual to-be-updated table. You might want to put the whole thing to a transaction to be able to roll back on error. See this reference.

Related

Updating one table's column in SQL Server from another

I have a table of measurements from weather stations, with station names (in Hebrew):
I also have created a table of those weather stations with their latitudes and longitudes:
I've written a query that should update the first table with the lat/longs from the second, but it's not working:
update t1
set t1.MeasurementLat = t2.Latitude,
t1.MeasurementLong = t2.Longitude
from [dbo].[Measurements] as t1
inner join [dbo].[StationCoords] as t2 on t1.StationName like t2.Station
I think there is a problem with the way the station name is being read, and perhaps something to do with encoding, because this query brings back an empty result, too:
SELECT TOP (5) *
FROM [dbo].[Measurements]
WHERE [StationName] = 'אריאל מכללה';
Any ideas?
Your example names are not the same. Perhaps this will work:
update m
set MeasurementLat = sc.Latitude,
MeasurementLong = sc.Longitude
from dbo.[Measurements] m join
dbo.[StationCoords] sc
on m.StationName like sc.Station + '%';

How to implement incremental load using insert/update instead of merge in stored procedure?

I have implemented incremental load using merge, but I want using insert/update. Please help.
This is the stored procedure for the merge method. The stored procedure below loads data from source only when there are new records inserted, else it will discard. Updates only when there are updates in the record.
ALTER PROCEDURE [dbo].[LOAD_DIM_ADDRESS]
AS
BEGIN
MERGE [VINCE_RETAIL_TEST].[dbo].[DIM_ADDRESS] AS T
USING (SELECT
'1' as [COMPANY_KEY],
C.[CUSTOMER_KEY],
A.[ADDRESS_ID], A.[ADDRESS_TYPE],
'0' as [REGION_KEY],
'-1' as [COUNTRY_KEY],
'-1' as [STATE_KEY],
A.[CITY], A.[POSTAL_CODE]
FROM
[AX_STAGING].[dbo].[DIM_ADDRESS] A
INNER JOIN
[VINCE_RETAIL_TEST].[dbo].[DIM_CUSTOMER] C ON C.[CUSTOMER_ID] = A.[CUSTOMER_ID]
AND C.[ADDRESS_ID] = A.[ADDRESS_ID]) AS S
ON (T.[ADDRESS_ID] = S.[ADDRESS_ID] AND T.[ADDRESS_TYPE]=S.[ADDRESS_TYPE])
WHEN MATCHED
THEN
UPDATE
SET
T.[COMPANY_KEY] = S.[COMPANY_KEY],
T.[CUSTOMER_KEY] = S.[CUSTOMER_KEY],
T.[ADDRESS_ID] = S.[ADDRESS_ID],
T.[ADDRESS_TYPE] = S.[ADDRESS_TYPE],
T.[REGION_KEY] = S.[REGION_KEY],
T.[COUNTRY_KEY] = S.[COUNTRY_KEY],
T.[STATE_KEY] = S.[STATE_KEY],
T.[CITY] = S.[CITY],
T.[POSTAL_CODE] = S.[POSTAL_CODE]
WHEN NOT MATCHED BY TARGET
THEN
INSERT ([COMPANY_KEY], [CUSTOMER_KEY], [ADDRESS_ID], [ADDRESS_TYPE],
[REGION_KEY], [COUNTRY_KEY], [STATE_KEY], [CITY],
[POSTAL_CODE])
VALUES (S.[COMPANY_KEY], S.[CUSTOMER_KEY], S.[ADDRESS_ID], S.[ADDRESS_TYPE],
S.[REGION_KEY], S.[COUNTRY_KEY], S.[STATE_KEY], S.[CITY],
S.[POSTAL_CODE]);
END
Thanks in advance
You need to differentiate when to use INSERT, when to use UPDATE. So for example, only when (S.[ADDRESS_ID], S.[ADDRESS_TYPE]) does not exist in the target table, then do the INSERT. The code is listed. Similarly you can write the UPDATE part as a practice. :)
INSERT [VINCE_RETAIL_TEST].[dbo].[DIM_ADDRESS]
([COMPANY_KEY], [CUSTOMER_KEY], [ADDRESS_ID], [ADDRESS_TYPE],
[REGION_KEY], [COUNTRY_KEY], [STATE_KEY], [CITY],
[POSTAL_CODE])
SELECT S.[COMPANY_KEY], S.[CUSTOMER_KEY], S.[ADDRESS_ID], S.[ADDRESS_TYPE],
S.[REGION_KEY], S.[COUNTRY_KEY], S.[STATE_KEY], S.[CITY],
S.[POSTAL_CODE]
FROM (SELECT
'1' as [COMPANY_KEY],
C.[CUSTOMER_KEY],
A.[ADDRESS_ID], A.[ADDRESS_TYPE],
'0' as [REGION_KEY],
'-1' as [COUNTRY_KEY],
'-1' as [STATE_KEY],
A.[CITY], A.[POSTAL_CODE]
FROM
[AX_STAGING].[dbo].[DIM_ADDRESS] A
INNER JOIN
[VINCE_RETAIL_TEST].[dbo].[DIM_CUSTOMER] C ON C.[CUSTOMER_ID] = A.[CUSTOMER_ID]
AND C.[ADDRESS_ID] = A.[ADDRESS_ID]) AS S
WHERE (S.[ADDRESS_ID], S.[ADDRESS_TYPE]) NOT IN (SELECT [ADDRESS_ID],[ADDRESS_TYPE] FROM [VINCE_RETAIL_TEST].[dbo].[DIM_ADDRESS])

Insert not working using MERGE in SQL server

I have a stored proc with the below query to insert/update using a MERGE in SQL Server but the query works fine for update, but its not working for Insert.
Although I gets correct updated records in Target but for new inserts, it fails.
Basically, i have 4 tables.SUPPORT_STAFF_BAK is the target table which needs to be updated from source table UNIQUE_DUP_TEST based on few conditions from other two tables(REF_FUNCTION,DATA_PERIOD) which i tried to fulfill using joins.
Based on the conditions, we need to check in target, if the same ggid exists for current data_period we need to update it else we need to insert new record again, based on the condition.
MERGE SUPPORT_STAFF_BAK AS SUPP_STAFF
USING
(SELECT G_UNIQUE.[GLOBAL_ID],
G_UNIQUE.[FIRST_NAME],
G_UNIQUE.[LAST_NAME],
G_UNIQUE.[EMAIL],
G_UNIQUE.[Gender],
G_UNIQUE.[DATE_OF_BIRTH],
G_UNIQUE.[PRODUCTION_UNIT_CODE],
ORG.[LEGAL_ENTITY_COUNTRY_CODE],
ORG.[LEGAL_ENTITY_COUNTRY],
G_UNIQUE.[JOB_NAME],
ORG.[BU_CODE],
ORG.[BU_NAME],
ORG.[SBU_CODE],
ORG.[SBU_NAME],
G_UNIQUE.[GRADE_LETTER],
CASE
WHEN G_UNIQUE.[EMPLOYEE_STATUS] = 'A' THEN 'Active'
WHEN G_UNIQUE.[EMPLOYEE_STATUS] = 'S' THEN 'Suspended'
WHEN G_UNIQUE.[EMPLOYEE_STATUS]= 'T' THEN 'Terminated'
END AS [EMPLOYEE_STATUS],
CASE WHEN G_UNIQUE.[CATEGORY] = 'DSS' THEN G_UNIQUE.[CATEGORY_DETAIL] ELSE ''
END AS [CATEGORY],
G_UNIQUE.[CATEGORY_DETAIL],
G_UNIQUE.[FIRST_JOINING_DATE],
PERIOD.DATA_PERIOD_ID
FROM UNIQUE_DUP_TEST G_UNIQUE
INNER JOIN GDH_ORG ORG
ON G_UNIQUE.PRODUCTION_UNIT_CODE=ORG.PRODUCTION_UNIT_CODE
INNER JOIN REF_FUNCTION FUNC
ON G_UNIQUE.CATEGORY_DETAIL=FUNC.FUNCTION_CODE
INNER JOIN DATA_PERIOD PERIOD
ON FUNC.FUNCTION_ID=PERIOD.FUNCTION_ID
WHERE PERIOD.DATA_YEAR=YEAR(GETDATE()) AND PERIOD.DATA_MONTH=MONTH(GETDATE())
) AS G_SOURCE
ON SUPP_STAFF.GGID = G_SOURCE.GLOBAL_ID AND SUPP_STAFF.PRODUCTION_UNIT_CODE=G_SOURCE.PRODUCTION_UNIT_CODE
AND SUPP_STAFF.DATA_PERIOD_ID=G_SOURCE.DATA_PERIOD_ID
WHEN MATCHED THEN
UPDATE SET
[SUPP_STAFF].[FIRST_NAME] = G_SOURCE.[FIRST_NAME],
[SUPP_STAFF].[LAST_NAME] = G_SOURCE.[LAST_NAME],
[SUPP_STAFF].[EMAIL] = G_SOURCE.[EMAIL],
[SUPP_STAFF].[GENDER] = G_SOURCE.[Gender],
[SUPP_STAFF].[DATE_OF_BIRTH] = G_SOURCE.[DATE_OF_BIRTH],
[SUPP_STAFF].[LEGAL_ENTITY_COUNTRY_CODE] = G_SOURCE.[LEGAL_ENTITY_COUNTRY_CODE],
[SUPP_STAFF].[LEGAL_ENTITY_COUNTRY_NAME] = G_SOURCE.[LEGAL_ENTITY_COUNTRY],
[SUPP_STAFF].[GCM_ROLE] = G_SOURCE.[JOB_NAME],
[SUPP_STAFF].[BU_CODE] = G_SOURCE.[BU_CODE],
[SUPP_STAFF].[BU_NAME] = G_SOURCE.[BU_NAME],
[SUPP_STAFF].[SBU_CODE] = G_SOURCE.[SBU_CODE],
[SUPP_STAFF].[SBU_NAME] = G_SOURCE.[SBU_NAME],
[SUPP_STAFF].[GRADE] = G_SOURCE.[GRADE_LETTER],
[SUPP_STAFF].[EMPLOYEE_STATUS] = G_SOURCE.[EMPLOYEE_STATUS],
[SUPP_STAFF].[EMPLOYEE_CATEGORY] = G_SOURCE.[CATEGORY],
[SUPP_STAFF].[START_DATE] = G_SOURCE.[FIRST_JOINING_DATE],
[SUPP_STAFF].[UPDATE_DATE] = GETDATE(),
[SUPP_STAFF].[UPDATE_USER] = CASE WHEN G_SOURCE.[EMPLOYEE_STATUS]='Terminated' THEN 'Delete'
WHEN G_SOURCE.[EMPLOYEE_STATUS]<>'Terminated' THEN 'Update'
END,
[SUPP_STAFF].[SUPPORT_STAFF_FUNCTION] = CASE WHEN G_SOURCE.[EMPLOYEE_STATUS]='Terminated' THEN NULL
WHEN G_SOURCE.[EMPLOYEE_STATUS]<>'Terminated' THEN G_SOURCE.[CATEGORY_DETAIL]
END
WHEN NOT MATCHED AND G_SOURCE.[CATEGORY] = 'CC1'
AND G_SOURCE.[EMPLOYEE_STATUS] IN ('A, S')
THEN
INSERT( [GGID],
[FIRST_NAME],
[LAST_NAME],
[EMAIL],
[GENDER],
[DATE_OF_BIRTH],
[LEGAL_ENTITY_COUNTRY_CODE],
[LEGAL_ENTITY_COUNTRY_NAME],
[GCM_ROLE],
[BU_CODE],
[BU_NAME],
[SBU_CODE],
[SBU_NAME],
[GRADE],
[EMPLOYEE_STATUS],
[EMPLOYEE_CATEGORY],
[START_DATE],
[UPDATE_DATE],
[UPDATE_USER],
[SUPPORT_STAFF_FUNCTION]
)
VALUES (
G_SOURCE.[GLOBAL_ID],
G_SOURCE.[FIRST_NAME],
G_SOURCE.[LAST_NAME],
G_SOURCE.[EMAIL],
G_SOURCE.[Gender],
G_SOURCE.[DATE_OF_BIRTH],
G_SOURCE.[LEGAL_ENTITY_COUNTRY_CODE],
G_SOURCE.[LEGAL_ENTITY_COUNTRY],
G_SOURCE.[JOB_NAME],
G_SOURCE.[BU_CODE],
G_SOURCE.[BU_NAME],
G_SOURCE.[SBU_CODE],
G_SOURCE.[SBU_NAME],
G_SOURCE.[GRADE_LETTER],
G_SOURCE.[EMPLOYEE_STATUS],
G_SOURCE.[CATEGORY_DETAIL],
G_SOURCE.[FIRST_JOINING_DATE],
GETDATE(),
'Insert',
G_SOURCE.[CATEGORY_DETAIL]
)
OUTPUT $action,
INSERTED.GGID AS GGID;
SELECT ##ROWCOUNT;
One of your assumptions is wrong. Either the source query has less rows than you think, or there is a match, or the insert condition is not met. Otherwise the query is OK.
To debug this I'd insert the source query into a temp table and manually inspect its contents to make sure they are what you expect.
You can then join to the target to see if your inserts maybe are converted to updates (e.g. select * from Source join Target on ...). Internally, a MERGE is just a full outer join anyway and you can reproduce that manually.
Right now nobody can tell you the exact answer. You need to debug this yourself and examine your data.
Finally I found the error. The error was at the below 2 places -
CASE WHEN G_UNIQUE.[CATEGORY] = 'DSS' THEN G_UNIQUE.[CATEGORY_DETAIL] ELSE '' END AS [CATEGORY],
I replaced it with
CASE WHEN G_UNIQUE.[CATEGORY] = 'DSS' THEN G_UNIQUE.[CATEGORY_DETAIL] ELSE ''
END AS [EMPLOYEE_FUNCTION],
Also I included one more column in my Source query which was missing-
G_UNIQUE.[CATEGORY],
Also, there below wrong code
WHEN NOT MATCHED AND G_SOURCE.[CATEGORY] = 'CC1'
AND G_SOURCE.[EMPLOYEE_STATUS] IN ('A, S')
was replaced by the below correct code-
WHEN NOT MATCHED AND G_SOURCE.[CATEGORY] = 'CC1'
AND G_SOURCE.[EMPLOYEE_STATUS] IN ('Active', 'Suspended')
Actually, I was missing 1 source column and was checking the value for the same while inserting and hence the insert was failing.
Also,in the source for Employee_status i checked the values as A,S and T and then replaced them with Active,Suspended,Terminated but while inserting in the When not matched , i was checking the value for A,S,T which every time was returning false and hence insert failed.

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;​

merge into matches woron

im trying to merge into a table.
this select doesnt find anything:
select * from dpr where dpr_qot_id=1111;
then i run this merge like the follwing:
MERGE INTO dpr d
USING (select dpr_ts, dpr_qot_id
from dpr
where dpr_qot_id = 1111
and dpr_ts = to_date('30.11.1999', 'DD.MM.YYYY')) s
on (s.dpr_ts = d.dpr_ts and s.dpr_qot_id = d.dpr_qot_id)
when not matched then
insert
(DPR_TS,
DPR_CLOSE,
DPR_OPEN,
DPR_HIGH,
DPR_LOW,
DPR_VOLUME,
DPR_QOT_ID)
values
(to_date('30.11.2010', 'DD.MM.YYYY'),
21.66,
21.75,
22.005,
21.66,
2556.00,
1111)
WHEN MATCHED THEN
UPDATE
set DPR_CLOSE = 21.66,
DPR_OPEN = 21.75,
DPR_HIGH = 22.005,
DPR_LOW = 21.66,
DPR_VOLUME = 2556.00;
and still this select doesn't find anything:
select * from dpr where dpr_qot_id=1111;
What am i doing wrong?
Thank you!
Greetings
Magda
Since there are no dpr rows where dpr_qot_id=1111, the source (USING) query of your MATCH will also contain no rows, so there is no data to be merged - and so nothing is done.

Resources