O problema é de resolução de nomes.
Quando você tem um parâmetro
hostname
e um hostname
coluna na tabela que você está referenciando, as regras de resolução de escopo causam confusão na maioria das pessoas. É por isso que muitas pessoas recomendam usar uma convenção de nomenclatura para parâmetros e variáveis locais que os diferencie dos nomes das tabelas. No meu código, por exemplo, eu uso p_
para prefixar nomes de parâmetros e l_
para prefixar variáveis locais. No seu código, quando você tiver
SELECT mySystems.SYSTEMID
INTO SysID
FROM mySystems
where mySystems.HOSTNAME = Hostname;
hostname
é resolvido como a coluna na tabela, não o parâmetro. Isso faz com que a consulta retorne todas as linhas da tabela em que hostname
não é null que causa o erro. Você pode prefixar explicitamente o nome do parâmetro com o nome da função para forçar hostname
para resolver para o parâmetro SELECT mySystems.SYSTEMID
INTO SysID
FROM mySystems
where mySystems.HOSTNAME = GET_SYSTEMID.Hostname;
Isso funciona. Mas adicionar o prefixo do nome da função geralmente é irritante. Se você adotar a convenção de prefixar nomes de parâmetros e nomes de variáveis locais, obterá algo como
FUNCTION GET_SYSTEMID(p_hostname varchar2)
RETURN NUMBER
IS
l_sysID number;
BEGIN
SELECT mySystems.SYSTEMID
INTO l_sysID
FROM mySystems
where mySystems.HOSTNAME = p_hostname;
return l_sysID;
END GET_SYSTEMID;
Isso também funciona e tende (na minha opinião) a ser mais claro do que adicionar prefixos de nomes de funções explícitos em todo o lugar.