Re: ctid

Lists: pgsql-es-ayuda
From: "Felipe Amezquita" <felmarla(at)gmail(dot)com>
To: postgresayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: ctid
Date: 2007-01-09 16:15:09
Message-ID: bf4cfe570701090815ib9be930x2ab9d70904a30aeb@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

estoy creando la siguiente funcion,pero entonces este me carga estos ctid
(12,5)
(12,6)

necesito hacer un delete del (12,6) entonces eso de diferente no me sirve
por que apenas estoy cargando los ctid,como mas puedo hacer.
create or replace function eliminar_ubiprograma_repetidos()
as
$body$
declare
var_dir numeric;
var_prg numeric;
cur_ubiprg refcursor;
begin
OPEN cur_ubiprg for select dir_codigo,prg_codigo,count(*) from
ubicacion_programa group by dir_codigo,prg_codigo having count(*)>1
LOOP
fetch cur_ubiprg into var_dir,var_prg;
select ctid from ubicacion_programa where prg_codigo=var_dir and
dir_codigo=var_prg

--
Ing Sistemas y Telecomunicaciones
Luis Felipe Lopez Amezquita
3008217523 - 3162589699


From: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
To: Felipe Amezquita <felmarla(at)gmail(dot)com>
Cc: postgresayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: ctid
Date: 2007-01-10 03:17:38
Message-ID: 20070110031738.GH11064@alvh.no-ip.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Felipe Amezquita escribió:

> create or replace function eliminar_ubiprograma_repetidos()
> as
> $body$
> declare
> var_dir numeric;
> var_prg numeric;
> cur_ubiprg refcursor;
> begin
> OPEN cur_ubiprg for select dir_codigo,prg_codigo,count(*) from
> ubicacion_programa group by dir_codigo,prg_codigo having count(*)>1
> LOOP
> fetch cur_ubiprg into var_dir,var_prg;
> select ctid from ubicacion_programa where prg_codigo=var_dir and
> dir_codigo=var_prg

No no no no no. Debes dejar de pensar en modo procedural. Debes dejar
de programar diciendole a la maquina paso por paso que es lo que debe
hacer. Debes encontrar la manera de decirle a la maquina _QUE_ es lo
que debe hacer, no _COMO_ hacerlo. Si no consigues pensar de esa manera
jamas lograras entender como hacer funcionar una base de datos.

Aca en tu funcion lo que estas haciendo es decir "por favor traigame
todos los CTIDs que cumplan tal condicion", y a continuacion pedir para
cada CTID conseguir que se haga tal o cual cosa. Eso es perdida de
tiempo y recursos y escribir mil lineas que estan de sobra.

Mira, aca un ejemplo de como se hace realmente:

alvherre=# create table duplos (a int );
CREATE TABLE
alvherre=# insert into duplos values (1);
INSERT 0 1
alvherre=# insert into duplos values (1);
INSERT 0 1
alvherre=# insert into duplos values (2);
INSERT 0 1
alvherre=# insert into duplos values (2);
INSERT 0 1
alvherre=# insert into duplos values (2);
INSERT 0 1
alvherre=# insert into duplos values (3);
INSERT 0 1
alvherre=# select * from duplos;
a
---
1
1
2
2
2
3
(6 rows)

Ok, hay duplicados. Como se eliminan? Observa esto:

alvherre=# select ctid, a from duplos;
ctid | a
-------+---
(0,1) | 1
(0,2) | 1
(0,3) | 2
(0,4) | 2
(0,5) | 2
(0,6) | 3
(6 rows)

Queremos dejar (0,1) pero eliminar (0,2); dejar (0,3) pero eliminar (0,4) y
(0,5); y dejar (0,6). Como se expresa esto? Observa:

alvherre=# select min(ctid), a from duplos group by a;
min | a
-------+---
(0,6) | 3
(0,3) | 2
(0,1) | 1
(3 rows)

Wow, aca tenemos justo los que queremos dejar! Ahora como se borra el resto?

alvherre=# delete from duplos where ctid not in (select min(ctid) from duplos group by a);
DELETE 3
alvherre=# select * from duplos;
a
---
1
2
3
(3 rows)

Listo. Nada de jugarretas con cursores ni loops.

Puedes perder todo el tiempo que quieras tonteando con shared_buffers y
discos en RAID y servidores gigantescos, pero si cuando te vas para tu
casa has dejado un loop en PL/pgSQL que podia haberse escrito como una
simple consulta, el rendimiento de tu servidor sera malo y la culpa sera
tuya.

Si _realmente_ quieres aprender a programar y dejar de tontear con Java
o Visual Basic, que son juguetes para niños, aprende LISP o Scheme y
veras como el mundo cambia de color de una forma que te sorprendera.

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


From: "ricardo yanguma" <ricardo(dot)yanguma(at)gmail(dot)com>
To: "Felipe Amezquita" <felmarla(at)gmail(dot)com>, postgresayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: ctid
Date: 2007-01-11 14:21:36
Message-ID: fbe285730701110621n31bcd6drb0be06c1e37c41f9@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

alvaro, donde puedo conseguir buena bibliografia de lo que tu estas diciendo
( LISP o Scheme)

Gracias

On 1/9/07, Alvaro Herrera <alvherre(at)commandprompt(dot)com> wrote:
>
> Felipe Amezquita escribió:
>
> > create or replace function eliminar_ubiprograma_repetidos()
> > as
> > $body$
> > declare
> > var_dir numeric;
> > var_prg numeric;
> > cur_ubiprg refcursor;
> > begin
> > OPEN cur_ubiprg for select dir_codigo,prg_codigo,count(*) from
> > ubicacion_programa group by dir_codigo,prg_codigo having count(*)>1
> > LOOP
> > fetch cur_ubiprg into var_dir,var_prg;
> > select ctid from ubicacion_programa where prg_codigo=var_dir and
> > dir_codigo=var_prg
>
> No no no no no. Debes dejar de pensar en modo procedural. Debes dejar
> de programar diciendole a la maquina paso por paso que es lo que debe
> hacer. Debes encontrar la manera de decirle a la maquina _QUE_ es lo
> que debe hacer, no _COMO_ hacerlo. Si no consigues pensar de esa manera
> jamas lograras entender como hacer funcionar una base de datos.
>
> Aca en tu funcion lo que estas haciendo es decir "por favor traigame
> todos los CTIDs que cumplan tal condicion", y a continuacion pedir para
> cada CTID conseguir que se haga tal o cual cosa. Eso es perdida de
> tiempo y recursos y escribir mil lineas que estan de sobra.
>
> Mira, aca un ejemplo de como se hace realmente:
>
> alvherre=# create table duplos (a int );
> CREATE TABLE
> alvherre=# insert into duplos values (1);
> INSERT 0 1
> alvherre=# insert into duplos values (1);
> INSERT 0 1
> alvherre=# insert into duplos values (2);
> INSERT 0 1
> alvherre=# insert into duplos values (2);
> INSERT 0 1
> alvherre=# insert into duplos values (2);
> INSERT 0 1
> alvherre=# insert into duplos values (3);
> INSERT 0 1
> alvherre=# select * from duplos;
> a
> ---
> 1
> 1
> 2
> 2
> 2
> 3
> (6 rows)
>
> Ok, hay duplicados. Como se eliminan? Observa esto:
>
> alvherre=# select ctid, a from duplos;
> ctid | a
> -------+---
> (0,1) | 1
> (0,2) | 1
> (0,3) | 2
> (0,4) | 2
> (0,5) | 2
> (0,6) | 3
> (6 rows)
>
> Queremos dejar (0,1) pero eliminar (0,2); dejar (0,3) pero eliminar (0,4)
> y
> (0,5); y dejar (0,6). Como se expresa esto? Observa:
>
> alvherre=# select min(ctid), a from duplos group by a;
> min | a
> -------+---
> (0,6) | 3
> (0,3) | 2
> (0,1) | 1
> (3 rows)
>
> Wow, aca tenemos justo los que queremos dejar! Ahora como se borra el
> resto?
>
> alvherre=# delete from duplos where ctid not in (select min(ctid) from
> duplos group by a);
> DELETE 3
> alvherre=# select * from duplos;
> a
> ---
> 1
> 2
> 3
> (3 rows)
>
>
> Listo. Nada de jugarretas con cursores ni loops.
>
> Puedes perder todo el tiempo que quieras tonteando con shared_buffers y
> discos en RAID y servidores gigantescos, pero si cuando te vas para tu
> casa has dejado un loop en PL/pgSQL que podia haberse escrito como una
> simple consulta, el rendimiento de tu servidor sera malo y la culpa sera
> tuya.
>
> Si _realmente_ quieres aprender a programar y dejar de tontear con Java
> o Visual Basic, que son juguetes para niños, aprende LISP o Scheme y
> veras como el mundo cambia de color de una forma que te sorprendera.
>
> --
> Alvaro Herrera
> http://www.CommandPrompt.com/
> The PostgreSQL Company - Command Prompt, Inc.
>
> ---------------------------(fin del mensaje)---------------------------
> TIP 7: no olvides aumentar la configuración del "free space map"
>


From: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
To: ricardo yanguma <ricardo(dot)yanguma(at)gmail(dot)com>
Cc: Felipe Amezquita <felmarla(at)gmail(dot)com>, postgresayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: ctid
Date: 2007-01-11 15:44:04
Message-ID: 20070111154404.GB20406@alvh.no-ip.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

ricardo yanguma escribió:
> alvaro, donde puedo conseguir buena bibliografia de lo que tu estas diciendo
> ( LISP o Scheme)

Para aprender LISP dices tu? No sabria decir. Como punto de partida
puedes echarle un vistazo al sitio de Paul Graham, quizas partiendo por
http://www.paulgraham.com/avg.html

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.