jeudi 23 avril 2009

Validation de procédures stockées dans la base SQL Server

Dans un projet, j’ai travaillé avec des applications qui utilisent de nombreuses procédures stockées. Ceci donne la facilité qu’en cas de bug urgent, nous pouvons corriger la procédure concernée sans faire une livraison complète de l’application.

Un jour, on est amené à faire de nettoyage dans la base de données afin de supprimer des colonnes non utilisées. Il nous fallait un moyen de vérifier la validité des procédures stockées après la suppression des colonnes.

Pour cela j’ai fait une application Windows qui permet de valider les objets dans la base de données.
Plus loin, j’ai développé un outil qui permet de comparer l’état des bases de données. Dans mon cas, je l’utilise pour comparer la base de données de développement et celle de la production. Le comparateur de bases de données sera abordé prochainement.

Ci-dessous un extrait de code pour valider les objets de la base de données:

// Connexion à la base de données
SqlConnection conn = new SqlConnection("Data Source=" + pServer + ";Initial Catalog="+pDb+";User Id="+login+";Password="+password+";");
conn.Open();

/*Requête sur la table système sysobjects pour récupérer les objets de la base de données suivant le type d’objet (P pour procédure stockée, V pour vue,…)
OBJECTPROPERTY (id, propriété): Retourne les informations concernant les objets (id = id de l’objet)
OBJECTPROPERTY(id,'ExecIsQuotedIdentOn') : retourne la propriété de QUOTED_IDENTIFIER lors de création de l’objet
OBJECTPROPERTY(id, 'ExecIsAnsiNullsOn') : retourne la propriété d’AISI NULLS lors de création de l’objet

*/
string cmdText = "SELECT name, OBJECTPROPERTY(id,'ExecIsQuotedIdentOn') as ident_on, " +
" OBJECTPROPERTY(id,'ExecIsAnsiNullsOn') as ainsi_null ,USER_NAME(uid) as owner " +
" FROM sysobjects WHERE xtype= '" + objectType+"'";
SqlDataAdapter daTable1 = new SqlDataAdapter(cmdText,conn);
DataSet ds = new DataSet("Table");
daTable1.Fill(ds);

// Parcourir les objets
foreach(DataRow row in ds.Tables[0].Rows)
{
StringBuilder sbCmd = new StringBuilder();
StringBuilder sbCmdProc = new StringBuilder();
string objectName = row["name"].ToString();
string owner = row["owner"].ToString();
string ansi_null = Convert.ToBoolean(row["ainsi_null"])?"ON":"OFF";
string ident_on = Convert.ToBoolean(row["ident_on"])?"ON":"OFF";
SqlCommand cmd = new SqlCommand("",conn);
try
{
// sp_helptext : récupérer la definition d’objet
cmd = new SqlCommand("exec sp_helptext '" + owner + "." + objectName+"';",conn);
cmd.CommandType = CommandType.Text;
SqlDataReader drDef = cmd.ExecuteReader();

while(drDef.Read())
{
sbCmdProc.Append(drDef["text"].ToString());
}
drDef.Close();

// Ne pas exécuter la requête/ mode parse
sbCmd.Append("set noexec on;");


// Proriété ansi_null d’objet
sbCmd.Append("set ansi_nulls "+ ansi_null +";");


// Proriété quoted_identifier d’objet
sbCmd.Append("set quoted_identifier "+ ident_on+";");
cmd = new SqlCommand(sbCmd.ToString(),conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();

// Executer l’objet
cmd = new SqlCommand(sbCmdProc.ToString(),conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
catch(Exception ex)
{
// Erreur dans l’exécution, l’objet n’est pas valide
// Ici, mettre un message d’erreur
}

finally
{
/*Mettre ainsi_null par défaut (ON) et quoted_identifier par défaut (OFF)
Et remettre en mode exécution
*/

sbCmd = new StringBuilder();
sbCmd.Append("set ansi_nulls ON;");
sbCmd.Append("set quoted_identifier OFF;");
sbCmd.Append("set parseonly off; set noexec off;");

cmd = new SqlCommand(sbCmd.ToString(),conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
// Fermer la connexion de la base de données
conn.Close();

jeudi 16 avril 2009

Checkout from SVN and Rebuild Solution File from Command Line

I create a .bat file to checkout an application source from SVN and to rebuild solution file without opening Visual studio .NET.

rem ****Déclare path to Tortoise and Visual Studio .NET ***
set path=%path%;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\

rem ****Checkout application source from SVN****

rem ****/closeonend:1 Close automatically Tortoise Dialog Box if no error TortoiseProc.exe /command:checkout /path:"D:\MyProject" /url:"https://svn.toto.com/svnrepos/MyProject/trunk" /closeonend:1

rem ****Rebuild solution in debug mode - output to log file****
devenv.exe /rebuild Debug "D:\MyProject\MyProject.sln" /out "d:\logMyProject"