Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

358
Vistas
Error de sintaxis de Postgres al usar insertar en conflicto

Dada una mesa

 CREATE TABLE balances ( username varchar(255) NOT NULL, currency varchar(255) NOT NULL, balance numeric NULL, CONSTRAINT balances_pkey PRIMARY KEY (username, currency) );

Después de intentar

 CREATE OR REPLACE FUNCTION merge_balance(username varchar(255), currency varchar(255), to_add numeric) RETURNS void AS $$ BEGIN INSERT INTO balances(username, currency, to_add) ON CONFLICT balances_pkey DO UPDATE SET balance = OLD.balance + to_add END; $$ LANGUAGE plpgsql;

yo obtengo

 ERROR: syntax error at or near "ON"

Mi versión de PostgreSQL (ejecutándose en un contenedor postgres: 11.5)

 SELECT version(); version ---------------------------------------------------------------------------------------------------------------------------------- PostgreSQL 11.5 (Debian 11.5-3.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit (1 row)

aquellos ; , $ las cosas son tan molestas y ahora me sale esta =_=
¿Alguien ha solucionado un problema así? ¡Gracias!

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Considerar:

 create or replace function merge_balance( p_username varchar(255), p_currency varchar(255), p_to_add numeric ) returns void as $$ begin insert into balances (username, currency, balance) values(p_username, p_currency, p_to_add) on conflict (username, currency) do update set balance = old.balance + p_to_add; end; $$ language plpgsql;

Razón fundamental:

  • necesita una cláusula VALUES() para enumerar los valores a insertar; también es una buena práctica rodear la lista de las columnas de destino; para esto, es mejor que no tenga argumentos de función que tengan el mismo nombre que las columnas de la tabla

  • el objetivo del conflicto debe estar entre paréntesis; puede usar un nombre de restricción, pero creo que es más claro usar los nombres de las columnas

over 4 years ago · Santiago Trujillo Denunciar

0

¿No debería ser

 INSERT INTO balances VALUES(username, currency, to_add) ON CONFLICT balances_pkey DO UPDATE SET balance = OLD.balance + to_add
over 4 years ago · Santiago Trujillo Denunciar

0

No puede usar "viejo" como lo está intentando. Lo que está haciendo es hacer referencia a la pseudo fila OLD generada por las declaraciones DML para los disparadores. Incluso si pudiera hacer referencia, sería NULL ya que todas las columnas antiguas son nulas en la inserción. Esto no es lo que quieres, el resultado sería nulo. Pero sí necesita crear un alias para la tabla para evitar ambigüedades en la cláusula de actualización. Además, no es necesario especificar límites en el encabezado de la función. Tratar:

 create or replace function merge_balance( p_username varchar , p_currency varchar , p_to_add numeric ) returns void language sql as $$ insert into balances as bal (username, currency, balance) values (p_username, p_currency, p_to_add) on conflict (username, currency) do update set balance = bal.balance + excluded.balance; $$;

Ver ejemplo completo aquí .

Como pensamiento posterior, supongo que podría usar old.balance usando old como el alias de la tabla.

 insert into balances as old (username, currency, balance) ...

Pero eso no me parece una buena idea, al menos a mí.,

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda