Procedure Avançada no Firebird, utilizando vários recursos ….

CREATE PROCEDURE SP_TIPODOCUMENTO_TEMPO (
    ipcodigotipodocumento integer,
    ipdatafinal date)
returns (
    opdataprevistaretirada date,
    opdatarealretirada date)
as
declare variable vtempoarquivoanos integer;
declare variable vtempoarquivomeses integer;
declare variable vtempoarquivoanosusuario integer;
declare variable vtempoarquivomesusuario integer;
declare variable vfinalconcessao varchar(1);
declare variable vtempoesperaano integer;
declare variable vtempoesperameses integer;
declare variable vdatafinalconcessao date;
declare variable vdiapadrao integer;
BEGIN
    VDIAPADRAO = 1;

    /* LEMBRANDO QUE NO PROGRAMA SÓ VOU ACEITAR 3 6 E 9 PARA OS MESES*/
    SELECT TEMPOARQUIVOANO, TEMPOARQUIVOMESES, TEMPOARQUIVOANOSUSUARIO, TEMPOARQUIVOMESUSUARIO, FINALCONCESSAO, TEMPOESPERAANO, TEMPOESPERAMESES
    FROM TIPODOCUMENTO
    WHERE CODIGOTIPODOCUMENTO = :IPCODIGOTIPODOCUMENTO
    INTO :VTEMPOARQUIVOANOS, :VTEMPOARQUIVOMESES, :VTEMPOARQUIVOANOSUSUARIO, :VTEMPOARQUIVOMESUSUARIO, :VFINALCONCESSAO, :VTEMPOESPERAANO, :VTEMPOESPERAMESES;

    IF (:VTEMPOARQUIVOANOS IS NULL) THEN
        VTEMPOARQUIVOANOS = 0;

    IF (:VTEMPOARQUIVOMESES IS NULL) THEN
        VTEMPOARQUIVOMESES = 0;

    IF (:VTEMPOARQUIVOANOSUSUARIO IS NULL) THEN
        VTEMPOARQUIVOANOSUSUARIO = 0;

    IF (:VTEMPOARQUIVOMESUSUARIO IS NULL) THEN
        VTEMPOARQUIVOMESUSUARIO = 0;

    IF (:VTEMPOESPERAANO IS NULL) THEN
        VTEMPOESPERAANO = 0;

    IF (:VTEMPOESPERAMESES IS NULL) THEN
        VTEMPOESPERAMESES = 0;

    IF (EXTRACT (MONTH FROM IPDATAFINAL) + :VTEMPOARQUIVOMESES < 12) THEN
    BEGIN
        OPDATAPREVISTARETIRADA =
        CAST((EXTRACT (MONTH FROM IPDATAFINAL) + :VTEMPOARQUIVOMESES) AS VARCHAR(5)) || ‘/’ ||
        :VDIAPADRAO || ‘/’ ||
        CAST((EXTRACT (YEAR FROM IPDATAFINAL) + :VTEMPOARQUIVOANOS) AS VARCHAR(5));

        /** NO CASO DE MESES MENORES **/
        IF (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES < 12) THEN
        BEGIN
            /** NO CASO DE MESES MENORES PREENCHIDOS OS MESES**/
            IF (:VTEMPOESPERAMESES <> 0) THEN
            BEGIN
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 1) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 3) ) THEN
                    OPDATAREALRETIRADA = ’04/01/’ || CAST(EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) AS VARCHAR(5));
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 4) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 6) ) THEN
                    OPDATAREALRETIRADA = ’07/01/’ || CAST(EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) AS VARCHAR(5));
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 7) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 9) ) THEN
                    OPDATAREALRETIRADA = ’10/01/’ || CAST(EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) AS VARCHAR(5));
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 10) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 12) ) THEN
                    OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1) AS VARCHAR(5));
                IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 = 0)) THEN
                    OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));

            END
            ELSE
            BEGIN
                /** NO CASO DE MESES MENORES PREENCHIDOS ANOS **/
                OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + VTEMPOESPERAANO)AS VARCHAR(5));
            END
        END
        ELSE
        BEGIN
            /** NO CASO DE MESES IGUAIS E MAIORES **/
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 1) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 3)) THEN
                OPDATAREALRETIRADA = ’04/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 4) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 6)) THEN
                OPDATAREALRETIRADA = ’07/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 7) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 9)) THEN
                OPDATAREALRETIRADA = ’10/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 10) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 12)) THEN
                OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 2 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 = 0)) THEN
                OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
        END
    END
    ELSE
    BEGIN
        /* CASO SEJA 12 TENHO QUE SOMAR 1 AO ANO*/
        IF (EXTRACT (MONTH FROM IPDATAFINAL) + :VTEMPOARQUIVOMESES = 12) THEN
        BEGIN
            OPDATAPREVISTARETIRADA =
            CAST(EXTRACT (MONTH FROM IPDATAFINAL) AS VARCHAR(5)) || ‘/’ ||
            :VDIAPADRAO || ‘/’ ||
            CAST((EXTRACT (YEAR FROM IPDATAFINAL) + :VTEMPOARQUIVOANOS + 1) AS VARCHAR(5));
        END
        ELSE
        BEGIN
            OPDATAPREVISTARETIRADA =
            CAST((EXTRACT (MONTH FROM IPDATAFINAL) – 12 + :VTEMPOARQUIVOMESES) AS VARCHAR(5)) || ‘/’ ||
            :VDIAPADRAO || ‘/’ ||
            CAST((EXTRACT (YEAR FROM IPDATAFINAL) + :VTEMPOARQUIVOANOS + 1) AS VARCHAR(5));
        END
        /** NO CASO DE MESES MENORES **/
        IF (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES < 12) THEN
        BEGIN
            /** NO CASO DE MESES MENORES PREENCHIDOS OS MESES**/
            IF (:VTEMPOESPERAMESES <> 0) THEN
            BEGIN
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 1) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 3) ) THEN
                    OPDATAREALRETIRADA = ’04/01/’ || CAST(EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) AS VARCHAR(5));
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 4) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 6) ) THEN
                    OPDATAREALRETIRADA = ’07/01/’ || CAST(EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) AS VARCHAR(5));
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 7) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 9) ) THEN
                    OPDATAREALRETIRADA = ’10/01/’ || CAST(EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) AS VARCHAR(5));
                IF ( (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) >= 10) AND (:VTEMPOESPERAMESES + EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) <= 12) ) THEN
                    OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1) AS VARCHAR(5));
                IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 = 0)) THEN
                    OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
            END
            ELSE
            BEGIN
                /** NO CASO DE MESES MENORES PREENCHIDOS ANOS **/
                OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + VTEMPOESPERAANO)AS VARCHAR(5));
            END
        END
        ELSE
        BEGIN
            /** NO CASO DE MESES IGUAIS E MAIORES **/
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 1) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 3)) THEN
                OPDATAREALRETIRADA = ’04/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 4) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 6)) THEN
                OPDATAREALRETIRADA = ’07/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 7) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 9)) THEN
                OPDATAREALRETIRADA = ’10/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 >= 10) AND (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 <= 12)) THEN
                OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 2 + VTEMPOESPERAANO)AS VARCHAR(5));
            IF ( (EXTRACT (MONTH FROM OPDATAPREVISTARETIRADA) + :VTEMPOESPERAMESES – 12 = 0)) THEN
                OPDATAREALRETIRADA = ’01/01/’ || CAST((EXTRACT (YEAR FROM OPDATAPREVISTARETIRADA) + 1 + VTEMPOESPERAANO)AS VARCHAR(5));
        END
    END

    IF (VFINALCONCESSAO = ‘S’) THEN
    BEGIN
        SELECT DATAFINAL FROM FINALCONCESSAO INTO :VDATAFINALCONCESSAO;
        IF (:VDATAFINALCONCESSAO > :OPDATAREALRETIRADA) THEN
        BEGIN
            OPDATAPREVISTARETIRADA = VDATAFINALCONCESSAO;
            OPDATAREALRETIRADA = VDATAFINALCONCESSAO;
        END
        SUSPEND;
        EXIT;
    END
    SUSPEND;
END^

Execute Statement com Firebird + Delphi.

Outro Execute Statement Brincando ainda mais no Delphi e no Firebird

Vc pode chamar no delphi desta maneira, olha o detalhe coloque entre aspas duplas e o que acontece bumba posso colocas um espaço no apelido de cada campo.

SELECT
OPCODIGOLOGON AS “CODIGO LOGON :”,
OPLOGON AS “LOGON :”,
OPSENHA AS “SENHA :”,
OPNIVEL AS “NIVEL :”,
OPCODIGOSETOR AS “CODIGO SETOR :”,
OPSETOR AS ” SETOR :”,
OPMNEMONICO AS “MNENOMICO :”
FROM SP_ACESSOS_SELECIONA(0,”,”,0,0,”,”,’NAO’,’1′)

CREATE PROCEDURE SP_ACESSOS_SELECIONA (
IPCODIGOLOGON INTEGER,
IPLOGON VARCHAR(20),
IPSENHA VARCHAR(10),
IPNIVEL INTEGER,
IPCODIGOSETOR INTEGER,
IPSETOR VARCHAR(20),
IPMNEMONICO VARCHAR(8),
IPPREENCHACAMPOS VARCHAR(3),
IPORDENAR VARCHAR(1000))
RETURNS (
OPCODIGOLOGON INTEGER,
OPLOGON VARCHAR(20),
OPSENHA VARCHAR(10),
OPNIVEL INTEGER,
OPCODIGOSETOR INTEGER,
OPSETOR VARCHAR(20),
OPMNEMONICO VARCHAR(8))
AS
DECLARE VARIABLE VSQL VARCHAR(1000);
BEGIN
VSQL = ‘SELECT A.CODIGOLOGON, L.LOGON, L.SENHA, L.NIVEL, A.CODIGOSETOR, S.SETOR, S.MNEMONICO’;
VSQL = VSQL || ‘ FROM LOGON L, SETOR S, ACESSOS A’;

IF (:IPCODIGOLOGON = 0) THEN
IPCODIGOLOGON = NULL;
IF (:IPLOGON = ”) THEN
IPLOGON = NULL;
IF (:IPSENHA = ”) THEN
IPSENHA = NULL;
IF (:IPNIVEL = 0) THEN
IPNIVEL = NULL;
IF (:IPCODIGOSETOR = 0) THEN
IPCODIGOSETOR = NULL;
IF (:IPSETOR = ”) THEN
IPSETOR = NULL;
IF (:IPMNEMONICO = ”) THEN
IPMNEMONICO = NULL;
IF ((:IPORDENAR = ”) OR (:IPORDENAR IS NULL)) THEN
IPORDENAR = ‘1’;
IF (:IPPREENCHACAMPOS = ”) THEN
IPPREENCHACAMPOS = ‘SIM’;

IF ( :IPPREENCHACAMPOS = ‘SIM’) THEN
BEGIN
–Se eu quiser coloca algum campo como obrigatório
IF ( (:IPLOGON IS NULL) ) THEN
BEGIN
EXCEPTION ERRO ‘PREENCHA OS CAMPOS OBRIGATÓRIOS’;
EXIT;
END
END

VSQL = VSQL || ‘ WHERE A.CODIGOLOGON = L.CODIGOLOGON AND A.CODIGOSETOR = S.CODIGOSETOR ‘;

–Neste Caso o And é obrigatório
IF (:IPCODIGOLOGON IS NOT NULL) THEN
VSQL = VSQL || ‘ AND A.CODIGOLOGON = ‘ || :IPCODIGOLOGON;

IF (:IPLOGON IS NOT NULL) THEN
VSQL = VSQL || ‘ AND L.LOGON LIKE ‘ || ”” || ‘%’ || :IPLOGON || ‘%’ || ””;

IF (:IPSENHA IS NOT NULL) THEN
VSQL = VSQL || ‘ AND L.SENHA LIKE ‘ || ”” || ‘%’ || :IPSENHA || ‘%’ || ””;

IF (:IPNIVEL IS NOT NULL) THEN
VSQL = VSQL || ‘ AND L.NIVEL = ‘ || :IPNIVEL;

IF (:IPCODIGOSETOR IS NOT NULL) THEN
VSQL = VSQL || ‘ AND A.CODIGOSETOR = ‘ || :IPCODIGOSETOR;

IF (:IPSETOR IS NOT NULL) THEN
VSQL = VSQL || ‘ AND S.SETOR LIKE ‘ || ”” || ‘%’ || :IPSETOR || ‘%’ || ””;

IF (:IPMNEMONICO IS NOT NULL) THEN
VSQL = VSQL || ‘ AND S.MNEMONICO LIKE ‘ || ”” || ‘%’ || :IPMNEMONICO || ‘%’ || ””;

VSQL = VSQL || ‘ ORDER BY ‘ || :IPORDENAR;

FOR
EXECUTE STATEMENT VSQL INTO :OPCODIGOLOGON, :OPLOGON, :OPSENHA, :OPNIVEL, :OPCODIGOSETOR, :OPSETOR, :OPMNEMONICO
DO

SUSPEND;

End