Acces key violations in append query - sql

I'm trying to run an append query, but I keep getting key violations, I think DelledningID is the culprit, but not sure how to fix this, as I shouldn't be touching that or ProjektID.
INSERT INTO ProjektDelledning ( ProjektID, DelledningID, SaneringsmetKode, DatoOprettet, DatoOpdateret )
SELECT ProjektDelledning.ProjektID, ProjektDelledning.DelledningID, NySaneringsData.SaneringsmetodeKode AS SaneringsmetKode, IIf([ProjektDelledning].[DatoOprettet] Is Null,Date$()+" "+Time$(),[ProjektDelledning].[DatoOprettet]) AS DatoOprettet, IIf([ProjektDelledning].[SaneringsmetKode] Is Null,Date$()+" "+Time$(),[ProjektDelledning].[DatoOpdateret]) AS DatoOpdateret
FROM NySaneringsData LEFT JOIN ProjektDelledning ON NySaneringsData.DelledningsID = ProjektDelledning.DelledningID
WHERE (((Exists (SELECT * FROM ProjektDelledning WHERE ProjektDelledning.SaneringsmetKode = NySaneringsData.SaneringsmetodeKode AND ProjektDelledning.DelledningID = NySaneringsData.DelledningsID))=False));
How do I got about fixing this? I tried removing Projekt ID and DelledningID from the query, but that gives a validations error instead.

You are approaching this incorrectly. You cannot insert new records into the ProjektDelledning without a "valid" project_id. You don't have a valid project_id and you cannot steal it from existing records because you would then create duplicate records and hit the validation error.
assuming your NySaneringsData has only unique delledningid,
try updating the ProjektDelledning table. something like.
update
ProjektDelledning INNER JOIN ProjektDelledning ON NySaneringsData.DelledningsID = ProjektDelledning.DelledningID
set
ProjektDelledning.SaneringsmetKode = NySaneringsData.SaneringsmetKode ,
ProjektDelledning.DatoOprettet = nz(ProjektDelledning.DatoOprettet, now()),
ProjektDelledning.DatoOpdateret = nz(ProjektDelledning.DatoOpdateret, now())
WHERE ( if any further conditions needed);
if NySaneringsData has duplicate delledningsid then you need to makesure which record you want to take over.

Related

Error #1093 - Table is specified twice, both as a target for 'DELETE' and as a separate source for data

I'm trying to delete duplicate rows in a table. The email field needs to be be unique in the table for the code after it to run. Here's my code:
DELETE FROM deleteRequests
WHERE Email NOT IN (
SELECT MAX(Email)
FROM deleteRequests
GROUP BY email);
The error I get is: '#1093 - Table 'deleteRequests' is specified twice, both as a target for 'DELETE' and as a separate source for data'
I think the problem is that I'm using mariadb 10.2 (which also means I can't use WITH CTE). I am not in control of updating this, so I need a workaround. Suggestions?
MySQL, MariaDB doesn't allow the table to be referenced again in a DELETE or UPDATE. An easy work-around is to use a JOIN:
DELETE dr
FROM deleteRequests dr LEFT JOIN
(SELECT MAX(email) as max_email
FROM deleteRequests
GROUP BY email
) dr2
ON dr2.email = dr.max_email
WHERE dr2.max_email IS NOT NULL;
Of course, this query is non-sensical because you are aggregating by email and choosing the max -- so all non-NULL emails will match.
Perhaps you want HAVING COUNT(*) = 1 in the subquery,.
I ended up creating a new table to work from.
CREATE TABLE deleteRequestsWorking as
SELECT MAX(mamaID) as mamaID, Email
FROM deleteRequests
GROUP BY mamaID;
This gave me the table I needed, and so instead of trying to get it to update my original table by using a LEFT JOIN and DELETE, I just used it. They're both temporary tables that get deleted at the end of the process, so it works.

What's wrong with my DELETE query

I've two tables with same columns. I'm trying to delete rows from table1 '600_LONDON_NUMBER' which are in table2 '600_LONDON_NUMBER1'. Below is my query but when I run it, MS Access says "Could not delete from the specified Tables". Please Help
DELETE [600_LONDON_NUMBER].*
FROM 600_LONDON_NUMBER INNER JOIN 600_LONDON_NUMBER1
ON ([600_LONDON_NUMBER].GFCID = [600_LONDON_NUMBER1].GFCID) AND ([600_LONDON_NUMBER].CUSTBaseNO = [600_LONDON_NUMBER1].[CUST Base NO]);
P.S. When I run the SELECT Statement for the same query, it retrives the data without any Issue. I've also checked that data is not readonly I can delete using simple DELETEquery.
you may use EXISTS to solve it
DELETE 600_LONDON_NUMBER.* FROM 600_LONDON_NUMBER
WHERE EXISTS (
SELECT 1 FROM 600_LONDON_NUMBER1
WHERE [600_LONDON_NUMBER].GFCID = [600_LONDON_NUMBER1].GFCID) AND
[600_LONDON_NUMBER].CUSTBaseNO = [600_LONDON_NUMBER1].[CUSTBaseNO]
)

MERGE vs. UPDATE

I was trying to look for it online but couldn't find anything that will settle my doubts.
I want to figure out which one is better to use, when and why?
I know MERGE is usually used for an upsert, but there are some cases that a normal update with with subquery has to select twice from the table(one from a where clause).
E.G.:
MERGE INTO TableA s
USING (SELECT sd.dwh_key,sd.serial_number from TableA#to_devstg sd
where sd.dwh_key = s.dwh_key and sd.serial_number <> s.serial_number) t
ON(s.dwh_key = t.dwh_key)
WHEN MATCHED UPDATE SET s.serial_number = t.serial_number
In my case, i have to update a table with about 200mil records in one enviorment, based on the same table from another enviorment where change has happen on serial_number field. As you can see, it select onces from this huge table.
On the other hand, I can use an UPDATE STATEMENT like this:
UPDATE TableA s
SET s.serial_number = (SELECT t.serial_number
FROM TableA#to_Other t
WHERE t.dwh_serial_key = s.dwh_serial_key)
WHERE EXISTS (SELECT 1
FROM TableA#To_Other t
WHERE t.dwh_serial_key = s.dwh_serial_key
AND t.serial_number <> s.serial_number)
As you can see, this select from the huge table twice now. So, my question is, what is better? why?.. which cases one will be better than the other..
Thanks in advance.
I would first try to load all necessary data from remote DB to the temporary table and then work with that temporary table.
create global temporary table tmp_stage (
dwh_key <your_dwh_key_type#to_devstg>,
serial_number <your_serial_number_type##to_devstg>
) on commit preserve rows;
insert into tmp_stage
select dwh_key, serial_number
from TableA#to_devstg sd
where sd.dwh_key = s.dwh_key;
/* index (PK on dwh_key) your temporary table if necessary ...*/
update (select
src.dwh_key src_key,
tgt.dwh_key tgt_key,
src.serial_number src_serial_number,
tgt.serial_number tgt_serial_number
from tmp_stage src
join TableA tgt
on src.dwh_key = tgt.dwh_key
)
set src_serial_number = tgt_serial_number;

Using a select statement as criteria for an update query

I'm trying to put together a query that updates a field within a table. I'm attempting to run a sub select query that gives me a number, and then use that number that resulted from the sub-query as part of the criteria for the update query.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] =[tbl_Foundation_Account].[Client_ID]
where ([tbl_Foundation_Account].[Foundation_Account_ID] =
(Select TOP 1 tbl_Foundation_Account.Foundation_Account_ID
FROM tbl_Foundation_Account
INNER JOIN [2_Import_tbl_AWCDSU]
ON tbl_Foundation_Account.Foundation_Account_ID =
[2_Import_tbl_AWCDSU].[ECPD Profile ID]))
My issue is I keep receiving this error
The multi-part identifier
tbl_Foundation_Account.Foundation_Account_ID" could not be bound.
Am I using the sub-query incorrectly? When I've received this error before, it's been because of some ambiguity in the table or field names, but this time I've checked for all that and it should be fine. Can anyone explain what SQL sin I have committed?
On the error
The multi-part identifier
tbl_Foundation_Account.Foundation_Account_ID" could not be bound.
This is because the table column [tbl_Foundation_Account].[Client_ID] does not exists in the scope of outer UPDATEquery .
The only table the outer query has an inkling about is [2_import_VZW_tbl_SMTN] and it does not have a column like [tbl_Foundation_Account].[Client_ID].
It is akin to writing a column name with a typo or like you said
When I've received this error before, it's been because of some
ambiguity in the table or field names
Please try a query like below.
Note that I am using Inner query syntax and ensuring that a single value is returned by using
select top 1 [Client_ID]
in the inner query. rest of the query syntax is same.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] =
(
select top 1 [Client_ID]
from [tbl_Foundation_Account]
where [Foundation_Account_ID] =
(
Select TOP 1 a.Foundation_Account_ID
FROM tbl_Foundation_Account a
INNER JOIN [2_Import_tbl_AWCDSU] b
ON a.Foundation_Account_ID = b.[ECPD Profile ID]
)
)
Another poster submitted this answer earlier, but then deleted it. I was able to try it before they deleted it and it works exactly how I needed it to work. I will use this as the right answer unless someone else can tell me why this is a bad Idea.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] = [tbl_Foundation_Account].[Client_ID]
from [tbl_Foundation_Account]
where ([tbl_Foundation_Account].[Foundation_Account_ID] =
(Select TOP 1 tbl_Foundation_Account.Foundation_Account_ID
FROM tbl_Foundation_Account
INNER JOIN [2_Import_tbl_AWCDSU]
ON tbl_Foundation_Account.Foundation_Account_ID = [2_Import_tbl_AWCDSU].[ECPD Profile ID]))

Compare Temp table and Main table to find matches

I have two tables #mtss table:
#mtss
( [MM],[YYYY],[month_Start],[month_Finish],[ProjectID],[ProjectedBillable],[ProjectedPayable],[ActualBilled],[ActualPaid],[Total_To_Bill],[Total_To_Pay])
tbl_Snapshot ([MM],[YYYY],[month_Start],[month_Finish],[ProjectID],[ProjectedBillable],[ProjectedPayable],[ActualBilled],[ActualPaid],[Total_To_Bill],[Total_To_Pay]
)
I need to compare two tables and find matches
if tbl_snapshot [MM] and [ProjectId] matches then delete record in tbl_snapshot and insert record from #mtts.
Thanks in advance.
Since you're on 2008, you can use MERGE to perform the as a single logical operation:
;merge into tbl_Snapshot s
using #mtss m on s.MM = m.MM and s.ProjectId = m.ProjectId
when matched then update
set
YYYY = m.YYYY,
month_Start = m.month_Start
/* Other columns as well, not going to type them all out */
;
This would also easily extend to other cases you may have to deal with, if the data only exists in one table and not the other, with addition match clauses.
Of course, thinking further, in this case a simple UPDATE would work also. A DELETE followed by an INSERT (where the deleted and inserted rows are related by a key) is the equivalent of an UPDATE.
Somethig like:
DELETE tbl_snapshot
FROM tbl_snapshot ss
INNER JOIN #mtss m ON m.MM = ss.MM AND m.ProjectId = ss.ProjectId
(I wrote the code directly to this editor so it might have errors, but it should give you an idea how to continue)