novembre
2011
Depuis sa version 8.1.6 ORACLE met à disposition les fonctions UTL_INADDR.GET_HOST_ADDRESS
et UTL_INADDR.GET_HOST_NAME
qui permettent respectivement de recupérer l’adresse ip et le nom d’une machine distante ou locale. Son équivalement SQL SERVER n’existe pas [jusqu’à SQL SERVER 2008 R2]. J’ai vu ça et là des tentatives de conception d’une telle fonction sous SQL SERVER. Preuve du besoin d’une telle fonction pour des traitements T-SQL. Les tentatives de création de telles fonctions font recours à des commandes systèmes ping, ipconfig ou nbtstat avec traitement de chaines de caractères. Mais l’un des principaux problèmes est que les chaines de caractères retournées par ces commandes dépendent de la langue de l’OS sans parler des problèmes de performances. Voici une fonction CLR pour SQL SERVER.
=> Sous ORACLE
UTL_INADDR.GET_HOST_ADDRESS('WWW.GOOGLE.FR')
--------------------------------------------------------------------------------
74.125.39.104
SQL> select UTL_INADDR.get_host_name('74.125.39.104') from dual;
UTL_INADDR.GET_HOST_NAME('74.125.39.104')
--------------------------------------------------------------------------------
fx-in-f104.1e100.net
SQL>
=> SOUS SQL SERVER : CLR
Pré-requis : .NET Framework 2.0
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Text;
public partial class GET_IP_or_NAME
{
[Microsoft.SqlServer.Server.SqlFunction(TableDefinition = "ip NVARCHAR(15),hostname NVARCHAR(128)",FillRowMethodName = "GetRow")]
public static IEnumerable F_HOST_IP_NAME(SqlString ip_or_hostname)
{
ArrayList rowsArray = new ArrayList();
GetHost_ip_name(ip_or_hostname, rowsArray);
return rowsArray;
}
public static void GetHost_ip_name(SqlString ip_or_hostname, ArrayList rowsArray)
{
try
{
// si le paramètre en entrée est est une adresse IP alors …
IPAddress ip;
if (IPAddress.TryParse(ip_or_hostname.ToString(), out ip))
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
byte[] buffer = Encoding.ASCII.GetBytes(ip.ToString());
int timeout = 120;
PingReply reply = pingSender.Send(ip.ToString(), timeout, buffer, options);
// si le ping est OK
if (reply.Status == IPStatus.Success)
{
IPHostEntry HostInfos = Dns.GetHostByAddress(ip.ToString());
string hostname = HostInfos.HostName.ToString();
object[] column = new object[2];
column[0] = ip;
column[1] = hostname;
rowsArray.Add(column);
}
}
// si le paramètre en entrée n'est pas une adresse IP alors …
else
{
IPHostEntry HostInfos = Dns.GetHostEntry(ip_or_hostname.ToString());
int j = HostInfos.AddressList.Length;
for (int i = 0; i < j; i++)
{
object[] column = new object[2];
column[0] = HostInfos.AddressList[i].ToString();
column[1] = ip_or_hostname.ToString();
rowsArray.Add(column);
}
}
}
catch (Exception e)
{
e.Source.ToString();
e.Message.ToString();
}
}
private static void GetRow(Object obj, out String ip, out String ip_or_hostname)
{
object[] row = (object[])obj;
ip = row[0].ToString();
ip_or_hostname = row[1].ToString();
}
};
Résultats
–> 1. Nom en paramètre
———————
SELECT ip,hostname FROM dbo.F_HOST_IP_NAME('www.google.fr')
74.125.39.104 www.google.fr
74.125.39.105 www.google.fr
74.125.39.106 www.google.fr
74.125.39.147 www.google.fr
74.125.39.99 www.google.fr
74.125.39.103 www.google.fr
–> 2. IP en paramètre
———————
SELECT ip,hostname FROM dbo.F_HOST_IP_NAME('74.125.39.104')
ip ——————– hostname
74.125.39.104 ——–fx-in-f104.1e100.net
Happy Query
———————————-
Etienne ZINZINDOHOUE
———————————-