2009-05-08 8 views
1

Est-il possible pour une fonction définie par l'utilisateur SQL CLR de renvoyer le type de données varbinary (MAX)?CLR UDF renvoyant Varbinary (MAX)

Dans la documentation, il mentionne:

« Les paramètres d'entrée et le type de retour d'une fonction scalaire à valeur peut être l'un des types de données scalaires pris en charge par SQL Server, à l'exception rowversion, texte, ntext, image, horodatage, table ou curseur. " - ils ne mentionnent pas varbinary, mais je ne suis pas sûr ...

J'ai quelques données de byte-array du côté .NET que j'ai besoin de retourner à SQL Server à partir du CLR, et j'essaie pour éviter d'avoir à le faire avec un paramètre de sortie d'une procédure stockée (c'est comme ça que je l'ai en test maintenant).

Merci!

Répondre

2

Si vous le définissez comme renvoyant un type de données SqlBytes, cela doit correspondre correctement à varbinary(MAX) dans SQL Server.

[SqlFunction] 
public static SqlBytes Function1() 
{ 
    return new SqlBytes(Encoding.UTF8.GetBytes("Hello world.")); 
} 

Alors que vous pouvez également utiliser le type de données SqlBinary, si vous déployez via Visual Studio, il sera mis en correspondance sur varbinary(8000) plutôt que varbinary(MAX).

+0

en utilisant Microsoft.SqlServer.Server; en utilisant System.Data.SqlTypes; –

0

Il semble que la réponse est oui - vous pouvez utiliser à la fois varbinary (MAX) en retournant "SqlBinary" ou vous pouvez utiliser SqlBytes comme recommandé ci-dessus.

6

Techniquement, il n'y a pas 8000 octets maximum dans l'interface de SQL Server au code CLR. C'est principalement une différence de la façon dont le wrapper T-SQL stocké Proc ou Function est défini. Cela signifie que si la procédure T-SQL ou la fonction qui appelle le code CLR définit RETURNS comme VARBINARY(MAX), elle doit être VARBINARY(MAX), que vous ayez spécifié ou non SqlBytes ou SqlBinary comme type de retour du code CLR.

Les deux SqlBytes et SqlBinary peuvent gérer la limite de 2 Go, MAIS la différence réside dans la façon dont le code CLR accepte les données. SqlBinary (tout comme SqlString) prend la valeur du paramètre tout à la fois tandis que SqlBytes (tout comme SqlChars) fournit une interface de diffusion en continu, donc il peut être plus efficace pour les très grandes valeurs.

Pour en revenir à la question que vous voyez avec l'emballage de fonction SQL pré-défini, que est était une question de la façon dont générer automatiquement s Visual Studio (techniquement SSDT) ​​d T-SQL. La valeur par défaut pour SqlBinary est était VARBINARY(8000) alors que la valeur par défaut pour SqlBytes est était VARBINARY(MAX). De la même manière, la valeur par défaut pour SqlString est était NVARCHAR(4000) tandis que la valeur par défaut pour SqlChars est était NVARCHAR(MAX). Ceux étaient les valeurs par défaut lorsque cette question a été posée. À partir de Visual Studio 2012 peut-être, la valeur par défaut a été modifiée pour utiliser MAX pour tous ces 4 types de données. Ce n'est pas forcément une bonne chose, car il y a un succès certain pour les types MAX par rapport aux types non-MAX.Donc, si vous n'avez pas besoin de plus de 8000 octets de VARBINARY ou 4000 octets de NVARCHAR, alors vous voulez remplacer la valeur par défaut en utilisant l'une des méthodes suivantes:

  1. Vous pouvez ALTER la fonction ou Proc définition après il est généré par Visual Studio, et dans ce cas, vous pouvez même modifier les types de données (des paramètres d'entrée ou des valeurs de retour) pour avoir une taille telle que VARBINARY(100) ou NVARCHAR(50).

  2. Vous pouvez utiliser le décorateur SqlFacet pour indiquer à Visual Studio/SSDT de générer automatiquement les définitions de fonction ou de procédure avec l'option de taille que vous préférez par rapport à la valeur par défaut. L'exemple suivant montre spécifiant la taille pour les deux paramètres d'entrée et de la valeur de retour (notez que -1 = MAX):

    [return: SqlFacet(MaxSize = -1)] 
    [Microsoft.SqlServer.Server.SqlFunction(Name = "FunctionName")] 
    public static SqlBinary FuncName([SqlFacet(MaxSize = 50)] SqlString InputParam) 
    

En utilisant l'une de ces deux méthodes que vous pouvez faire soit SqlBinary ou SqlBytes carte soit VARBINARY(1 - 8000) ou VARBINARY(MAX). De même, vous pouvez faire SqlString ou SqlChars carte soit NVARCHAR(1 - 4000) ou NVARCHAR(MAX).

Questions connexes