El problema es uno de resolución de nombres.
Cuando tienes un parámetro hostname
y un hostname
columna en la tabla a la que hace referencia, las reglas de resolución de alcance causan confusión a la mayoría de las personas. Es por eso que muchas personas recomiendan usar una convención de nomenclatura para parámetros y variables locales que los diferencie de los nombres de tablas. En mi código, por ejemplo, uso p_
para prefijar nombres de parámetros y l_
para prefijar variables locales.
En tu código, cuando tienes
SELECT mySystems.SYSTEMID
INTO SysID
FROM mySystems
where mySystems.HOSTNAME = Hostname;
hostname
se resuelve como la columna de la tabla, no como el parámetro. Esto hace que la consulta devuelva cada fila de la tabla donde hostname
no es nulo lo que causa el error. Puede prefijar explícitamente el nombre del parámetro con el nombre de la función para forzar hostname
para resolver el parámetro
SELECT mySystems.SYSTEMID
INTO SysID
FROM mySystems
where mySystems.HOSTNAME = GET_SYSTEMID.Hostname;
Eso funciona. Pero agregar el prefijo del nombre de la función generalmente se vuelve molesto. Si adopta la convención de anteponer nombres de parámetros y nombres de variables locales, obtendrá 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;
Eso también funciona y tiende (en mi opinión) a ser más claro que agregar prefijos de nombres de funciones explícitos por todas partes.