insert into select oracle - sql

i need insert rows on a table that comes of other, the colums in the table are empty but in te base table are full, im using a insert into select but i get: 'Error SQL: ORA-00926'
INSERT INTO TABLEROS.V_GRR_EEAF (PER_ID, EDAD, F_NACIMIENTO, CICLO_VITAL, GENERO_HOM, PERT_ETNICA, DISCAP
)A
(SELECT PER_ID, EDAD, F_NACIMIENTO, CICLO_VITAL, GENERO_HOM, PERT_ETNICA, DISCAP
FROM FUENTES.V_GRR_EEAF#CONSULTAFUENTES80 B
WHERE A.ID_BASE = B.ID_BASE
);

If I understand, you want to update empty columns in A where id_base exists in B and the updated values should be same as columns in B.
use this statement, it works:
MERGE INTO TABLEROS.V_GRR_EEAF a
USING FUENTES.V_GRR_EEAF#CONSULTAFUENTES80 b
ON(a.ID_BASE = b.ID_BASE)
WHEN MATCHED THEN
UPDATE SET
a.PER_ID = b.PER_ID,
a.EDAD = b.EDAD,
a.F_NACIMIENTO = b.F_NACIMIENTO,
a.CICLO_VITAL = b.CICLO_VITAL,
a.GENERO_HOM = b.GENERO_HOM,
a.PERT_ETNICA = b.PERT_ETNICA,
a.DISCAP = b.DISCAP;
commit;

Related

SQL: Error when using MERGE

I'm trying to update or insert one table based on the entries present in another table. But when I try to use MERGE to accomplish this. I'm getting below error message.
Error: The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.
Do I have to include more conditions in ON clause?
Code:
IF EXISTS (SELECT ShoppingCartNo FROM tbPOValidation WHERE ShoppingCartNo <> '')
BEGIN
MERGE tbPOValidation AS t
USING tbPOValidationTemp AS s
ON (CONVERT(VARCHAR(30),t.ShoppingCartNo)+CONVERT(VARCHAR(30),t.lineitemNo)+CONVERT(VARCHAR(30),t.PONo)) =
(CONVERT(VARCHAR(30),s.ShoppingCartNo)+CONVERT(VARCHAR(30),s.lineitemNo)+CONVERT(VARCHAR(30),s.PONo))
--When records are matched, update
--the records if there is any change
WHEN MATCHED AND (CONVERT(VARCHAR(30),t.ShoppingCartNo)+CONVERT(VARCHAR(30),t.lineitemNo)+CONVERT(VARCHAR(30),t.PONo)) =
(CONVERT(VARCHAR(30),s.ShoppingCartNo)+CONVERT(VARCHAR(30),s.lineitemNo)+CONVERT(VARCHAR(30),s.PONo))
THEN
UPDATE SET t.SupplierName = s.SupplierName, t.DUNS = s.DUNS, t.PONo = s.PONo, t.LineItemNo = s.LineItemNo, t.PurchDocItemDesc = s.PurchDocItemDesc,
t.POIssueDate = s.POIssueDate, t.DeliveryDate = s.DeliveryDate, t.PurchDocType = s.PurchDocType, t.MtrNo = s.MtrNo, t.Location = s.Location,
t.PayTerms = s.PayTerms, t.BlanketNo = s.BlanketNo, t.BlanketLineItemNo = s.BlanketLineItemNo, t.ShoppingCartNo = s.ShoppingCartNo,
t.SHCItmNo = s.SHCItmNo, t.ItemPricing = s.ItemPricing, t.ItmPrcCurrency = s.ItmPrcCurrency, t.Per = s.Per, t.POValue = s.POValue,
t.POValueCurrency = s.POValueCurrency, t.Qty = s.Qty, t.UOM = s.UOM, t.MFGName = s.MFGName, t.MFGPartNO = s.MFGPartNO, t.Description = s.Description,
t.Remarks = s.Remarks, t.Accept = s.Accept, t.AcceptedBy = s.Duns, t.AcceptedOn = GETDATE(), t.RejectionReason = s.RejectionReason
--When no records are matched, insert
--the incoming records from s
--table to t table
WHEN NOT MATCHED BY TARGET THEN
INSERT (SupplierName, DUNS, PONo, LineItemNo, PurchDocItemDesc, POIssueDate, DeliveryDate, PurchDocType, MtrNo,
Location, PayTerms, BlanketNo, BlanketLineItemNo, ShoppingCartNo, SHCItmNo, ItemPricing, ItmPrcCurrency, Per, POValue, POValueCurrency,
Qty, UOM, MFGName, MFGPartNO, Description, Remarks, Accept, AcceptedBy, AcceptedOn, RejectionReason)
VALUES (s.SupplierName, s.DUNS, s.PONo, s.LineItemNo, s.PurchDocItemDesc, s.POIssueDate, s.DeliveryDate, s.PurchDocType, s.MtrNo,
s.Location, s.PayTerms, s.BlanketNo, s.BlanketLineItemNo, s.ShoppingCartNo, s.SHCItmNo, s.ItemPricing, s.ItmPrcCurrency, s.Per, s.POValue,
s.POValueCurrency,s.Qty, s.UOM, s.MFGName, s.MFGPartNO, s.Description, s.Remarks, s.Accept, s.AcceptedBy, s.AcceptedOn, s.RejectionReason);
END
It is likely that the concatenation of fields is not unique i.e 10 11 12 would be equal to 101 11 2. Put special characters between the fields:
ON (CONVERT(VARCHAR(30),t.ShoppingCartNo)+'~' +CONVERT(VARCHAR(30),t.lineitemNo)+'~'+CONVERT(VARCHAR(30),t.PONo)) =
(CONVERT(VARCHAR(30),s.ShoppingCartNo)+'~' +CONVERT(VARCHAR(30),s.lineitemNo)+'~' +CONVERT(VARCHAR(30),s.PONo))

My UPDATE statement with WHERE EXISTS does not limit to the SELECT statement results

I have data in a temporary table and I am checking for duplicates in two other tables. I want to set a flag on the temp table (SET DupFlag = TRUE) for all duplicates found. My SELECT statement works perfectly, returning only the 48 duplicates that I entered to test with. But when I add UPDATE and WHERE EXISTS, every record in idTempImport2 is set to TRUE instead of just the 48 records returned from the SELECT statement. Is my syntax wrong? It looks like this:
UPDATE idTempImport2 as tmp2 SET DupFlag = TRUE
WHERE EXISTS
(SELECT * FROM idTempImport2 tmp2
LEFT JOIN (SELECT im.idDate, im.UserID, im.ActionID, im.IsHC, idn.Epic1, idn.Epic2
FROM idMain AS im
INNER JOIN idNotes AS idn ON im.aID = idn.MainID
WHERE idDate BETWEEN "2017-01-02" AND "2017-01-31") AS qry
ON qry.idDate = tmp2.idDate AND qry.UserID = tmp2.UserID AND qry.ActionID = tmp2.ActionID AND qry.Epic1 = clng(tmp2.Epic1) AND qry.Epic2 = clng(tmp2.Epic2)
WHERE qry.Epic1 <> NULL);
I think the ultimate issue is that you want a correlated subquery. As written, the subquery has no connection to the outer query, so it is likely that at least one row meets the condition. So, everything gets updated.
I think you intend:
UPDATE idTempImport2 as tmp2
SET DupFlag = TRUE
WHERE EXISTS (SELECT im.idDate, im.UserID, im.ActionID, im.IsHC, idn.Epic1, idn.Epic2
FROM idMain AS im INNER JOIN
idNotes AS idn
ON im.aID = idn.MainID
WHERE idDate BETWEEN "2017-01-02" AND "2017-01-31" AND
im.idDate = tmp2.idDate AND im.UserID = tmp2.UserID AND
im.ActionID = tmp2.ActionID AND
?.Epic1 = clng(tmp2.Epic1) AND ?.Epic2 = clng(tmp2.Epic2)
);

MERGE statement using OUTPUT with WHERE condition

I'm trying to insert data from one system into another so I keep an intermediate mapping table to keep the ids from old and new table.
I'm using a MERGE condition, is there any way to
DECLARE #TenantId INT = 1
MERGE dbo.[Account] AS t
USING (SELECT m.[AccountId],
m.[TenantId],
a.[ID_Account],
a.[Account_No],
a.[Account_Name],
FROM [Client1].dbo.[Account] a
LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account] AND m.[TenantId] = #TenantId
) AS s
ON (t.[AccountId] = s.[AccountId] AND t.[TenantId] = s.[TenantId])
WHEN NOT MATCHED THEN
INSERT ([TenantId], [Number], [Name], [Active] )
VALUES (#TenantId, s.[Account_No], s.[Account_Name], 1)
OUTPUT #TenantId, inserted.[AccountId], s.[ID_Account] INTO migration.[Account];
This is fine, but if I try to run it a second time, the records are inserted again on my migration.[Account] table keeping repeated data. Is there any way to put a where condition on the output?
When you check to see if values from the source exist in the target, you check to see if the AccountId from migration.Account is equal to the AccountId from dbo.Account. You output the results to the migration table, but the original record still exists so it will be included in subsequent executions of the merge.
To fix your problem you need to either:
delete the original record
Add an isUpdated column in the migration table that you update after insertion and will prevent the source from being loaded.
Update the AccountId with the new AccountId so it will match the condition on subsequent executions.
Have the new record somehow cancel the original in the source record.
Here's a method with a new isUpdated and updates the accountId column:
UPDATE m SET
isUpdated = 1,
AccountId = o.NewAccountId
FROM migration.Account [m]
INNER JOIN (
MERGE dbo.[Account] AS t
USING (SELECT m.[AccountId],
m.[TenantId],
a.[ID_Account],
a.[Account_No],
a.[Account_Name],
FROM [Client1].dbo.[Account] a
LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account]
AND m.[TenantId] = #TenantId
WHERE m.isUpdated IS NULL OR m.isUpdated = 0
) AS s
ON (t.[AccountId] = s.[AccountId] AND t.[TenantId] = s.[TenantId])
WHEN NOT MATCHED THEN
INSERT ([TenantId], [Number], [Name], [Active] )
VALUES (#TenantId, s.[Account_No], s.[Account_Name], 1)
OUTPUT #TenantId, s.AccountId [OriginalAccountId], inserted.[NewAccountId]
) [o] ON o.TenantId = m.TenantId AND o.OriginalAccountId = m.AccountId
What you want to do is do updates on when matched:
MERGE into dbo.[Account] AS destination
USING (SELECT m.[AccountId],
m.[TenantId],
a.[ID_Account],
a.[Account_No],
a.[Account_Name],
FROM [Client1].dbo.[Account] a
LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account] AND m.[TenantId] = #TenantId
) AS holdinarea
ON (destination.[AccountId] = holdinarea.[AccountId] AND destination.[TenantId] = holdinarea.[TenantId])
WHEN MATCHED THEN
UPDATE set [AccountId]=holdinarea.accountid,
[TenantId]=holdinarea.tenantID
WHEN NOT MATCHED THEN
INSERT ([TenantId], [Number], [Name], [Active] )
VALUES (holdingarea.TenantId, holdingarea.[Account_No], holdingarea.[Account_Name], 1);

Adding data to new column in table (insert into or update)

What I try to achieve is to update all data, so the new data goes into Row_ID and all other columns.
I have a table created db.test
I added new column Row_ID(integer)
This ise the first Code for inserting data to table
Insert into db.test
(
STRING0 ,
CONTACT ,
STRING2 ,
TEMPLATE,
NAME ,
EXEC_ID,
SENDDATE,
OPENDATE,
CLICKDATE
)
SELECT
acc.STRING0 ,
a.CONTACT ,
acc.STRING2 ,
a.TEMPLATE ,
a.NAME ,
a.EXEC_ID,
a.SENDDATE,
A.OPENDATE,
A.CLICKDATE
FROM db.account acc
Join db.activity a
ON acc.object_id = a.rep_contact
left JOIN db.VAL v1
ON v1.row_id = a.CAMPAIGN_TYPE
AND (v1.OBJ_FIELD_ID in(850))
left JOIN db.VAL v2
ON v2.row_id = a.CAMPAIGN_TYPE
AND (v2.OBJ_FIELD_ID in(851))
The values for ROW_ID comes from table db.VAL, but do I use update like this
Update db.test
( row_id, -- This column as integer has greated
string0,
etc...)
Select
v1.row_Id,
acc.STRING0,
etc....
Ending is the same
I tried this kind of update query, but it didn't work.
What should I change?
Because I would prefer to just update table, not drop, create new, and all new data.
NB! SQL Server ( Sybase)
As data is already inserted in the table, now you will have to update
the values in new column row_id. Following pseudo code will work
just make sure the from clause fetches the correct value of v1.row_Id:
UPDATE db.test
SET row_id = v1.row_Id
FROM db.test t1
JOIN db.account acc ON acc.STRING0 = t1.STRING0
--all match columns will go here
AND acc.STRING2 = t1.STRING2
JOIN db.activity a ON acc.[object_id] = a.rep_contact
AND a.CONTACT = t1.CONTACT
AND a.TEMPLATE = t1.TEMPLATE
AND a.NAME = t1.NAME
AND a.EXEC_ID = t1.EXEC_ID
AND a.SENDDATE = t1.SENDDATE
AND A.OPENDATE = t1.OPENDATE
AND A.CLICKDATE = t1.CLICKDATE
LEFT JOIN db.VAL v1 ON v1.row_id = a.CAMPAIGN_TYPE
AND (v1.OBJ_FIELD_ID in(850))
LEFT JOIN db.VAL v2 ON v2.row_id = a.CAMPAIGN_TYPE
AND (v2.OBJ_FIELD_ID in(851))

Update error column parameter does not exist

Trying to execute this query I've this error:
Update failed. 3810: Column/parameter 'edw_workarea.A.A' does not exist.
I'm using Teradata database.
UPDATE A
FROM EDW_WORKAREA.bs A,
(
SELECT stg.ccir_ind_id,
stg.orig_ccir_id
FROM EDW_WORKAREA.se stg
INNER JOIN best_svc bc
ON stg.ccir_ind_id = bc.ccir_ind_id
WHERE stg.deliverability_score < '6'
AND stg.ccir_ind_id IN (SELECT stg.ccir_ind_id
FROM EDW_WORKAREA.se stg
WHERE stg.orig_ccir_id IS NULL
OR stg.orig_ccir_id = ''
GROUP BY
stg.ccir_ind_id
HAVING COUNT(*) = 1)
) t
SET A.orig_ccir_id = t.orig_ccir_id
WHERE A.ccir_ind_id = t.ccir_ind_id;
All the tables and columns exist in database. And subquery in t was executing successfully alone.
Can any one point me where the error is ?
On Teradata, you shouldn't qualify your columns in the SET clause, so change your SQL to something like:
update EDW_WORKAREA.bs
from (
select ...
) t
set orig_ccir_id = t.orig_ccir_id
where EDW_WORKAREA.bs.ccir_ind_id = t.ccir_ind_id;