Olá, Fernando!
Pelo que entendi da sua dúvida, você está usando a função NVL para retornar um valor vazio ('') caso o código do produto não exista na tabela PRODUTO_EXERCICIO. Isso parece correto.
No entanto, acredito que o problema que você está enfrentando é devido ao fato de que, se o código do produto não existir na tabela, a consulta SELECT não retornará nenhuma linha, e o PL/SQL lançará uma exceção NO_DATA_FOUND.
Para tentar resolver isso, você pode usar um bloco de exceção para tratar essa situação. Aqui está um exemplo de como você pode fazer isso:
CREATE OR REPLACE FUNCTION f_obter_categoria_produto(
p_id PRODUTO_EXERCICIO.COD%type
)
-- tipo de retorno da função, poderia ser o tipo VARCHAR2 ou o mesmo tipo do campo CATEGORIA
RETURN PRODUTO_EXERCICIO.CATEGORIA%type
IS
v_categoria PRODUTO_EXERCICIO.CATEGORIA%type;
BEGIN
BEGIN
select categoria into v_categoria from PRODUTO_EXERCICIO where cod = p_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_categoria := '';
END;
RETURN v_categoria;
END;
Nesse código, se a consulta SELECT não retornar nenhuma linha, a exceção NO_DATA_FOUND será lançada. O bloco de exceção irá capturar essa exceção e atribuir um valor vazio ('') à variável v_categoria. Assim, a função retornará um valor vazio quando o código do produto não existir.
Espero ter entendido e conseguido ajudar. Qualquer coisa manda aqui de novo. Bons estudos!