Subject | RE: [firebird-support] UPDATE sql with join like search |
---|---|
Author | Svein Erling Tysvær |
Post date | 2013-02-25T13:29:14Z |
>I'm currently trying to create update sql for something likeThis can be very slow, Virgo, but I guess you already know that.
>
>UPDATE TABLE1 T
>SET T.VALUE1 = NULL
>WHERE
> T.VALUE1 IN (SELECT A.VALUE1 FROM TABLE2 A WHERE VALUE2 = ?)
>But I'd like to do it so, that it uses indexes, likeDepends on which Firebird version you use.
>SELECT T.*
>FROM TABLE1 T JOIN TABLE2 A ON T.VALUE1 = A.VALUE1 WHERE A.VALUE2 = ?
>
>There are indexes on T.VALUE1 and A.VALUE2, so the plan is something like
>PLAN JOIN (A INDEX (TABLE2_$_VALUE2), T INDEX (TABLE1_$_VALUE1))
>
>Is it even possible without using stored procedure?
Try either:
EXECUTE BLOCK AS
DECLARE VARIABLE V1 INTEGER;
BEGIN
FOR SELECT DISTINCT VALUE1 FROM TABLE2 WHERE VALUE2 = <whatever> INTO :V1 DO
BEGIN
UPDATE TABLE1
SET VALUE1 = NULL
WHERE VALUE1 = :V1;
END
END
or
EXECUTE BLOCK AS
DECLARE VARIABLE V1 INTEGER;
BEGIN
FOR SELECT DISTINCT T.ID
FROM TABLE1 T
JOIN TABLE2 A ON T.VALUE1 = A.VALUE1
WHERE A.VALUE2 = <whatever> INTO :V1 DO
BEGIN
UPDATE TABLE1
SET VALUE1 = NULL
WHERE ID = :V1;
END
END
If you use an old version where EXECUTE BLOCK isn't available, you could try:
UPDATE TABLE1 T
SET T.VALUE1 = NULL
WHERE
EXISTS(SELECT * FROM TABLE2 A WHERE VALUE2 = ? AND T.VALUE1 = A.VALUE1)
The last alternative will still use NATURAL, but once upon a time Firebird didn't transform IN into EXISTS (that's why I stopped using IN <subselect> last century), so it could be considerably quicker than your alternative.
HTH,
Set