Exercise involving Function in Postgresql

Asked

Viewed 150 times

0

The question would be as follows:

With the following Bank:

Telefone (id, numero, operadora_id)
Cliente (id, cpf, nome, rg, sexo, uf)
Operadora (id, nome, cnpj)
Contrato(id, cliente_id, telefone_id, plano_id, data_contrato, valor_final)
Plano (id, valor, operadora_id, descricao)

This is what you should do:

Uma função que receba o id de um cliente e de uma operadora, e 
verifique se o cliente já possui algum telefone da operadora, se 
sim, deve dar um desconto de 50% no seu contrato que possui o maior 
valor. Senão deve criar um contrato do cliente com essa operadora, 
usando o menor valor do plano desta operadora.

I have already managed to make a function that returns if in fact the client has a contract with the operator and if yes gives a 50% discount in the contract of higher value, however I could not make that if such contract does not exist, create a new contract between this client and the operator using a plan of this operator of lower value.

CREATE OR REPLACE FUNCTION QUEST3A
(CLI_ID INTEGER, OPE_ID INTEGER) 
RETURNS VARCHAR
AS 
$$
DECLARE
  CLI_NOME VARCHAR;
  RESULTADO BOOL;
BEGIN
  SELECT CLI.NOME INTO CLI_NOME
  FROM CLIENTE CLI
  LEFT JOIN CONTRATO CON    ON CLI.ID = CON.CLIENTE_ID
  LEFT JOIN TELEFONE TEL    ON TEL.ID = CON.TELEFONE_ID
  LEFT JOIN PLANO PLA       ON PLA.ID = CON.PLANO_ID
  LEFT JOIN OPERADORA OPE ON OPE.ID = PLA.OPERADORA_ID
  WHERE CLI.ID = CLI_ID AND OPE.ID = OPE_ID;

  IF CLI_NOME IS NULL THEN
    /*if dont't exists enrollment*/
        RESULTADO := FALSE;

  ELSE
    /*if it exists*/
    RESULTADO := TRUE;
    UPDATE CONTRATO
    SET VALOR_FINAL = X.RESULTADO/2
    FROM    
    (
        SELECT CON.ID, MAX(CON.VALOR_FINAL) AS RESULTADO
        FROM CLIENTE CLI
        LEFT JOIN CONTRATO CON  ON CLI.ID = CON.CLIENTE_ID
        LEFT JOIN TELEFONE TEL  ON TEL.ID = CON.TELEFONE_ID
        LEFT JOIN PLANO PLA     ON PLA.ID = CON.PLANO_ID
        LEFT JOIN OPERADORA OPE ON OPE.ID = PLA.OPERADORA_ID
        WHERE CLI.ID = CLI_ID AND TEL.ID = OPE_ID
        GROUP BY CON.ID
        ORDER BY CON.VALOR_FINAL DESC
        LIMIT 1
    )X
    WHERE X.ID = CONTRATO.ID;
  END IF;

RETURN RESULTADO;
END;
$$
LANGUAGE PLPGSQL;

I really appreciate anyone who can help me. Forte Abraço.

1 answer

0

The answer I’ve found so far would be this

 INSERT INTO CONTRATO(CLIENTE_ID, TELEFONE_ID, DATA_CONTRATO, PLANO_ID, VALOR_FINAL) 
        values
        (
            CLI_ID, 
            (
                SELECT TEL2.ID 
                FROM CONTRATO CON2
                INNER JOIN TELEFONE TEL2  ON CON2.TELEFONE_ID = TEL2.ID
                INNER JOIN CLIENTE CLI2 ON CON2.CLIENTE_ID = CLI2.ID
                INNER JOIN OPERADORA OPE2 ON TEL2.OPERADORA_ID = OPE2.ID
                WHERE CLI2.ID = CLI_ID
                LIMIT 1
            ),
            /*DATA_CONTRATO*/
            CURRENT_DATE,
            /*PLANO_ID*/
            (SELECT ID FROM PLANO WHERE OPERADORA_ID = OPE_ID ORDER BY VALOR ASC LIMIT 1),
            /*VALOR_FINAL*/
            (SELECT VALOR FROM PLANO WHERE OPERADORA_ID = OPE_ID ORDER BY VALOR ASC LIMIT 1)
        );

Which would be in the first block of IF/ELSE within Function, however I believe is not the most elegant way to resolve this issue.

Is there any other way? Thanks in advance.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.