Juan escribió: > Alvaro > > > Al compilar esa funcion me sale un error > ERROR: error de sintaxis en o cerca de «column» > LINE 67: quote_ident(column.attname) || E') INTO l;\n';
Meh. Eso se debe a que "column" es una palabra reservada; en mi código tengo "col", no "column", y por alguna razón lo cambié al publicar en el blog. En 8.4 funciona bien con "column", pero desde 9.0 ya no funciona. Usa la versión adjunta, que funciona en 9.1. (acabo de notar que me olvidé de considerar attisdropped) -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
create or replace function toastcheck_writer(text) returns void language plpgsql as $ff$ declare func text; funcname text; col record; pkc record; indent text; colrec record; pkcols text; pkformat text; pk_col_ary text[]; begin pkcols = ''; pkformat = ''; pk_col_ary = '{}'; funcname = 'toastcheck__' || $1; FOR pkc IN EXECUTE $f$ SELECT attname FROM pg_attribute JOIN pg_class ON (oid = attrelid) JOIN pg_index on (pg_class.oid = pg_index.indrelid and attnum = any (indkey)) WHERE pg_class.oid = '$f$ || $1 || $f$ '::regclass and indisprimary $f$ LOOP IF pkcols = '' THEN pkcols = quote_ident(pkc.attname); pkformat = '%'; ELSE pkcols = pkcols || ', ' || quote_ident(pkc.attname); pkformat = pkformat || ', %'; END IF; pk_col_ary = array_append(pk_col_ary, quote_ident(pkc.attname)); END LOOP; /* * This is the function header. It's basically a constant string, with the * table name replaced a couple of times and the primary key columns replaced * once. Make sure we don't fail if there's no primary key. */ IF pkcols <> '' THEN pkcols = ', ' || pkcols; pkformat = ', PK=( ' || pkformat || ' )'; END IF; func = $f$ CREATE OR REPLACE FUNCTION $f$ || funcname || $f$() RETURNS void LANGUAGE plpgsql AS $$ DECLARE rec record; BEGIN FOR rec IN SELECT ctid $f$ || pkcols || $f$ FROM $f$ || $1 || $f$ LOOP DECLARE f record; l int; BEGIN SELECT * INTO f FROM $f$ || $1 || $f$ WHERE ctid = rec.ctid; -- make sure each column is detoasted and reported separately $f$; /* We now need one exception block per toastable column */ indent = ' '; FOR col in SELECT attname FROM pg_attribute JOIN pg_class on (oid=attrelid) WHERE pg_class.oid = $1::regclass and attlen = -1 LOOP func := func || indent || E'BEGIN\n'; func := func || indent || $f$ SELECT length(f.$f$ || quote_ident(col.attname) || E') INTO l;\n'; /* The interesting part here needs some replacement of the PK columns */ func := func || indent || $f$EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'TID %$f$ || pkformat || $f$, column "$f$ || col.attname || $f$": exception {{%}}', rec.ctid, $f$; /* This iterates zero times if there are no PK columns */ FOR colrec IN SELECT f.i[a] AS pknm FROM (select pk_col_ary as i) as f, generate_series(array_lower(pk_col_ary, 1), array_upper(pk_col_ary, 1)) as a LOOP func := func || $f$ rec.$f$ || colrec.pknm || $f$, $f$; END LOOP; func := func || E'sqlerrm;\n'; func := func || indent || E'END;\n'; END LOOP; /* And this is our constant footer */ func := func || $f$ END; END LOOP; END; $$; $f$; EXECUTE func; RAISE NOTICE $f$Successfully created function %()$f$, funcname; RETURN; END; $ff$;
- Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda@postgresql.org) Para cambiar tu suscripción: http://www.postgresql.org/mailpref/pgsql-es-ayuda