2014-04-23 1 views
1

Celui-ci m'a empêché de rester connecté pendant quelques jours. Il est mon premier Dabble avec CLR & UDF ...La fonction définie par l'utilisateur SQL CLR (C#) ajoute un caractère nul ( 0) entre chaque caractère existant dans la chaîne renvoyée

J'ai créé une fonction définie par l'utilisateur qui prend une chaîne multiligne en entrée, il scanne et remplace une certaine ligne dans la chaîne avec une solution de rechange si trouvé. S'il n'est pas trouvé, il ajoute simplement la ligne désirée à la fin. (Voir le code)

Le problème, semble-t-il, survient lorsque la chaîne finale (ou Stringbuilder) est convertie en SqlString ou en SqlChars. La chaîne retournée et retournée contient toujours le caractère Nul à chaque deuxième caractère (affichage via la sortie de la console, ils sont affichés comme des espaces).

Je manque probablement quelque chose de fondamental sur UDF et/ou CLR.

Aidez-nous!

code (je laisse dans le stringbuilder commenté qui était ma première tentative ... changé de chaîne normale dans une tentative désespérée de trouver la question):

[Microsoft.SqlServer.Server.SqlFunction] 
[return: SqlFacet(MaxSize = -1, IsFixedLength = false)] 
//public static SqlString udf_OmaChangeJob(String omaIn, SqlInt32 jobNumber) { 
public static SqlChars udf_OmaChangeJob(String omaIn, SqlInt32 jobNumber) { 

    if (omaIn == null || omaIn.ToString().Length <= 0) return new SqlChars(""); 
    String[] lines = Regex.Split(omaIn.ToString(), "\r\n"); 

    Regex JobTag = new Regex(@"^JOB=.+$"); 
    //StringBuilder buffer = new StringBuilder(); 
    String buffer = String.Empty; 
    bool matched = false; 

    foreach (var line in lines) { 
     if (!JobTag.IsMatch(line)) 
      //buffer.AppendLine(line); 
      buffer += line + "\r\n"; 
     else { 
      //buffer.AppendLine("JOB=" + jobNumber); 
      buffer += ("JOB=" + jobNumber + "\r\n"); 
      matched = true; 
     } 
    } 
    if (!matched) //buffer.AppendLine("JOB=" + jobNumber); 
     buffer += ("JOB=" + jobNumber) + "\r\n"; 

    //return new SqlString(buffer.ToString().Replace("\0",String.Empty)) + "blablabla"; 
    // buffer = buffer.Replace("\0", "|"); 
    return new SqlChars(buffer + "\r\nTheEnd"); 

} 
+0

Les chaînes .Net sont [encodées UTF16] (http://stackoverflow.com/q/1018915/314291), à savoir 2 octets par caractère? – StuartLC

+0

Cela semble être une cause potentielle. Je donne à la fonction une valeur de varchar (donc 8 bits) ... C# String veut 16 bits ... donc peut-être quelque part les nuls sont ajoutés lors de la conversion en 16 bits? – Ricky

+0

Désolé tout ... Je pense que c'est un délit de harcèlement total ... à la recherche du problème au mauvais endroit. Je vais vérifier cela avant de supprimer cette question. – Ricky

Répondre

0

Je sais que dans mes expériences, le paramètre Omain devrait être de type SqlString et quand vous allez pour recueillir sa valeur/processus, définissez une variable locale:

string omaString = omaIn != SqlString.Null ? omaIn.Value : string.empty; 

Puis, quand vous revenez sur un chemin de code, pour remballer la chaîne en C#, vous aurez besoin de définir

return omaString == string.empty ? new SqlString.Null : new SqlString(omaString); 

J'ai eu quelques matches de catch amusants apprendre le transfert complexe entre les types locaux et sortants, en particulier avec les TVF CLR.

Espérons que cela peut aider!

Questions connexes