Procedimiento almacenado de Firebird para concatenar todos los valores de campo de varias filas

StackOverflow https://stackoverflow.com/questions/183675

Pregunta

mi objetivo es escribir un proceso almacenado que pueda recopilar todos los valores de campo de varias filas en una sola variable de salida (tal vez varchar (some_length)). Puede parecer una solución extraña, pero estoy bastante seguro de que es la única que puedo usar en esa situación. No he usado Firebird antes y los procedimientos almacenados se ven muy diferentes a los de otros sistemas de db conocidos. Mi Firebird es 1.5 y dialecto 3 (no estoy seguro de lo que significa). Entonces, tal vez alguien podría ayudarme con un ejemplo de algoritmo.

¿Fue útil?

Solución

El siguiente procedimiento hace lo que usted describe:

SET TERM !!;
CREATE PROCEDURE concat_names
  RETURNS (concat VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(100);
BEGIN
  concat = '';
  FOR SELECT first_name || ' ' || last_name FROM employee INTO :name
  DO BEGIN
    concat = concat || name || ', ';
  END
END!!
SET TERM ;!!
EXECUTE PROCEDURE concat_names;

Pero cuestiono la sabiduría de esta solución. ¿Cómo sabe que VARCHAR es lo suficientemente largo para todas las filas en su conjunto de datos deseado?

Es mucho más fácil y seguro ejecutar una consulta para devolver el resultado a una aplicación fila por fila. Cada lenguaje de programación de aplicaciones tiene métodos para concatenar cadenas, pero lo más importante es que tienen métodos más flexibles para administrar el crecimiento de los datos.

Por cierto, " dialecto " en Firebird e InterBase se refiere a un modo de compatibilidad que se introdujo para que las aplicaciones desarrolladas para InterBase 5.x puedan funcionar con versiones posteriores de InterBase y Firebird. Eso fue hace casi diez años, y AFAIK hoy no hay necesidad de usar nada más bajo que el dialecto 3.

Otros consejos

Debe probar los valores nulos al concatenar, aquí hay un ejemplo para dos campos y un separador entre ellos:

    CREATE PROCEDURE CONCAT(
    F1 VARCHAR(385),
    F2 VARCHAR(385),
    SEPARATOR VARCHAR(10))
RETURNS (
    RESULT VARCHAR(780))
AS
begin

  if ((:f1 is not null) and (:f1 <> '')) then
    result = :f1;

  if ((:f2 is not null) and (:f2 <> '')) then
    if ((result is not null) and (result <> '')) then
      begin
        if ((:separator is not null) and (separator <> '')) then
          result = result||separator||f2;
        else
          result = result||f2;
      end
    else
      result = f2;

  suspend;
end

Devolver varias filas usando los procedimientos almacenados de Firebird es muy fácil.

No use:

execute procedure proc_name(value);

En su lugar use:

select * from proc_name(value);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top