Subject | Re: [firebird-support] Merge in Fb3 fails |
---|---|
Author | setysvar |
Post date | 2016-05-14T23:01:31Z |
>I thought this working in Fb 2.5, but maybe not.updated occasionally with brand new zipcodes.
>I have a zipcode table with multiples of some zipcodes. it gets
>I want to merge it into a ref table with unique zipcodes.The codewithout merge works:
>T2.ZipCode=ZipCodeRef.ZipCode)
>insert into ZipCodeRef (ZipCode, Longitude, Latitude)
> select distinct T2.ZipCode, T2.Longitude, T2.Latitude
> from ZipCodeDataBus T2
> where not exists
>(select first 1 ZipCodeRef.Zipcode from ZipCodeRef where
> and T2.ZipCode <> '00000';T2.Longitude, T2.Latitude);
>
>Above works. Merge below fails:
>
>merge into ZipCodeRef T1
>using ZipCodeDataBus T2
>on T2.ZipCode = T1.ZipCode
>when not matched then
>insert (ZipCode, Longitude, Latitude) values (T2.ZipCode,
>C:\WINDOWS\SYSTEM32\firebird.msg not found
>Message: isc_dsql_execute2 failed
>SQL Message : -803
>can't format message 13:197 -- message file
>Engine Code : 335544665on table "ZIPCODEREF"
>Engine Message :
>violation of PRIMARY or UNIQUE KEY constraint "UKZIPCODEREF_ZIPCODE"
>Problematic key value is ("ZIPCODE" = '00501')After the first insert,I would expect a match to be found, and the
>
>in the source table there are multiple instances of zipcode '00501'.
subsequent >insert to be avoided.
>Since I rarely use MERGE and haven't even tried Fb3, please don't trust
>Is there something wrong with my SQL?
my answer!
First, I can confirm that Fb 2.5 (at least the somewhat old version I
use) accepts ambiguous statements like yours.
I find your expectation of one insert going through and the other to be
eliminated slightly problematic. Say ZipCodeDataBus contained (random
numbers for longitude/latitude)
ZipCode Longitude Latitude
00501 34.59 45.54
00501 62.32 67.12
Since a table basically is an unordered dataset, what you say you expect
is that zip-code 00501 is inserted once and that the longitude/latitude
inserted should be random (amongst those appearing for 00501). I would
prefer if Firebird for queries like yours (*) actually checked for
values existing in the tables before the statement was executed rather
than the current state after halfway executing your query. Hence, I like
that Firebird reports the error you observe.
It may be that longitude and latitude doesn't vary between rows for the
same zipcode in ZipCodeDataBus (your successful query indicates that,
but there's no way Firebird can know that). If so, I'd recommend you to
tell Firebird that by modifying your query:
merge into ZipCodeRef T1
using (select distinct ZipCode, Longitude, Latitude from ZipCodeDataBus) T2
on T2.ZipCode = T1.ZipCode
when not matched then
insert (ZipCode, Longitude, Latitude) values (T2.ZipCode, T2.Longitude,
T2.Latitude);
HTH,
Set
(*) For statements containing WHEN MATCHED it can be somewhat harder to
prevent ambiguity. Firebird seems to select randomly when doing a small
test on Fb 2.5 - I'd probably preferred an error (although the main
problem was my ambiguous (test) query, I like to be told when I create
ambiguity)!