Обсуждение: IF...THEN...ELSE on INSERT

Поиск
Список
Период
Сортировка

IF...THEN...ELSE on INSERT

От
Vincent AE Scott
Дата:
What's the fastest / most effecient way todo a test on an insert
operation and then change the SQL that gets exeuted?

Specifically, i want to check if a row already exists, and then instead
of inserting the row, just increment a counter for that row.

your TIA,
-vince

--

PGP key:  http://codex.net/pgp/pgp.asc

Re: IF...THEN...ELSE on INSERT

От
Andrew McMillan
Дата:
On Sat, 2001-12-08 at 00:34, Vincent AE Scott wrote:
> What's the fastest / most effecient way todo a test on an insert
> operation and then change the SQL that gets exeuted?
>
> Specifically, i want to check if a row already exists, and then instead
> of inserting the row, just increment a counter for that row.

I usually find this best implemented in a PL/PGSQL function:

CREATE FUNCTION myfunc( TEXT, NUMBER ) RETURNS INT4 AS '
   DECLARE
      p_1 ALIAS FOR $1;
      p_2 ALIAS FOR $2;
      curr_val TEXT;
   BEGIN
      SELECT <something> INTO curr_val FROM mytable
                                        WHERE table_id = p_1;
      IF FOUND THEN
        UPDATE mytable SET upfield = p_2
                                        WHERE table_id = p_1;
      ELSE
        INSERT INTO mytable (table_id, upfield)
                                        VALUES( p_1, p_2 );
      END IF;
      RETURN <whatever>;
   END;
' LANGUAGE 'plpgsql';

Hope that helps,
                    Andrew.
--
--------------------------------------------------------------------
Andrew @ Catalyst .Net.NZ Ltd, PO Box 11-053, Manners St, Wellington
WEB: http://catalyst.net.nz/        PHYS: Level 2, 150-154 Willis St
DDI: +64(4)916-7201    MOB: +64(21)635-694    OFFICE: +64(4)499-2267


Re: IF...THEN...ELSE on INSERT

От
Vincent AE Scott
Дата:
Andrew McMillan(andrew@catalyst.net.nz)@Sat, Dec 08, 2001 at 12:56:29AM +1300:
> On Sat, 2001-12-08 at 00:34, Vincent AE Scott wrote:
> > What's the fastest / most effecient way todo a test on an insert
> > operation and then change the SQL that gets exeuted?
> >
> > Specifically, i want to check if a row already exists, and then instead
> > of inserting the row, just increment a counter for that row.
>
> I usually find this best implemented in a PL/PGSQL function:
>
> CREATE FUNCTION myfunc( TEXT, NUMBER ) RETURNS INT4 AS '
>    DECLARE
>       p_1 ALIAS FOR $1;
>       p_2 ALIAS FOR $2;
>       curr_val TEXT;
>    BEGIN
>       SELECT <something> INTO curr_val FROM mytable
>                                         WHERE table_id = p_1;
>       IF FOUND THEN
>         UPDATE mytable SET upfield = p_2
>                                         WHERE table_id = p_1;
>       ELSE
>         INSERT INTO mytable (table_id, upfield)
>                                         VALUES( p_1, p_2 );
>       END IF;
>       RETURN <whatever>;
>    END;
> ' LANGUAGE 'plpgsql';
>
> Hope that helps,

Thanks for that, and yes it does help somewhat, but it appears somewhat
cumbersome to me.  It appears to me ( but i could be well out of whack )
that the function is losely linked to the table.  If i change the table
definition ( like adding an extra column ) do i have to modify the
function aswell?

Is there anyway i can just modify the behaviour of an insert statement
to transparently do this for me.  That way at least the database clients
dont have to implicitly know about this function/feature.  Does that
make sense?

TIA,
-vince

--

PGP key:  http://codex.net/pgp/pgp.asc

Re: IF...THEN...ELSE on INSERT

От
Andrew McMillan
Дата:
On Sat, 2001-12-08 at 02:13, Vincent AE Scott wrote:
>
> Thanks for that, and yes it does help somewhat, but it appears somewhat
> cumbersome to me.  It appears to me ( but i could be well out of whack )
> that the function is losely linked to the table.  If i change the table
> definition ( like adding an extra column ) do i have to modify the
> function aswell?
>
> Is there anyway i can just modify the behaviour of an insert statement
> to transparently do this for me.  That way at least the database clients
> dont have to implicitly know about this function/feature.  Does that
> make sense?

Yep, that does make sense.  What you are asking for is effectively an
'INSERT OR UPDATE <table> (<field list> ) VALUES( <value list> ) ...'
syntax.

This is being looked at in some areas ("CREATE OR REPLACE FUNCTION",
"CREATE OR REPLACE VIEW", ...) for 7.3, I believe.  Whether or not there
will be an "INSERT OR UPDATE ..." statement included in there I am not
sure.  I am pretty sure it has been proposed, and I know it would make
things easier for many programmers, myself included :-)

I think that it might be possible to write a function to do what you
want generically in 7.1 or later, but it would be complex.  PL/PGSQL
will let you PERFORM a query you have constructed as a string, and you
can pass a row to a function, so you could (perhaps) do something very
complicated and unmaintainable there.

You might be better with a more complex language like PL/Perl for
something along those lines, or with a C function.

Regards,
                    Andrew.
--
--------------------------------------------------------------------
Andrew @ Catalyst .Net.NZ Ltd, PO Box 11-053, Manners St, Wellington
WEB: http://catalyst.net.nz/        PHYS: Level 2, 150-154 Willis St
DDI: +64(4)916-7201    MOB: +64(21)635-694    OFFICE: +64(4)499-2267