CLR UDF que devuelve Varbinary (MAX)
-
20-08-2019 - |
Pregunta
¿Es posible que una función definida por el usuario de SQL CLR devuelva el tipo de datos varbinary (MAX)?
En la documentación que menciona:
" Los parámetros de entrada y el tipo devuelto por una función de valor escalar pueden ser cualquiera de los tipos de datos escalares admitidos por SQL Server, excepto la conversión de fila, texto, ntext, imagen, marca de tiempo, tabla o cursor. " - no mencionan varbinary, pero no estoy seguro ...
Tengo algunos datos de matriz de bytes del lado .NET que necesito devolver a SQL Server desde el CLR, y estoy tratando de evitar tener que hacerlo con un parámetro de salida de un procedimiento almacenado (así es como Lo tengo trabajando en la prueba ahora).
¡Gracias!
Solución
Si lo define como devolver un SqlBytes tipo de datos, esto debería correlacionarse correctamente con varbinary (MAX)
en SQL Server.
[SqlFunction]
public static SqlBytes Function1()
{
return new SqlBytes(Encoding.UTF8.GetBytes("Hello world."));
}
Aunque también puede usar el SqlBinary tipo de datos, si implementa a través de Visual Studio, se asignará a varbinary (8000)
en lugar de varbinary (MAX)
.
Otros consejos
Técnicamente no hay un máximo de 8000 bytes en la interfaz de SQL Server al código CLR. Es principalmente una diferencia de cómo se define el contenedor de T-SQL Stoc Proc o Function. Es decir, si el Proc T-SQL o la Función que llama al código CLR define RETURNS
como VARBINARY (MAX)
, entonces será VARBINARY (MAX)
, ya sea que haya especificado o no SqlBytes
o SqlBinary
como el tipo de retorno del código CLR.
Tanto SqlBytes
como SqlBinary
pueden manejar el límite de 2 GB, PERO la diferencia está en cómo el código CLR acepta los datos. SqlBinary
(al igual que SqlString
) toma el valor del parámetro de una vez mientras SqlBytes
(al igual que SqlChars
) proporciona un interfaz de transmisión por lo que podría ser más eficiente para valores muy grandes.
Volviendo al problema que está viendo con el contenedor de funciones SQL predefinido, que es fue una cuestión de cómo Visual Studio (técnicamente SSDT) ??genera automáticamente s d el T-SQL. El valor predeterminado para SqlBinary
es era VARBINARY (8000)
mientras que el valor predeterminado para SqlBytes
es era VARBINARY (MAX)
. De la misma manera, el valor predeterminado para SqlString
es era NVARCHAR (4000)
mientras que el valor predeterminado para SqlChars
is was NVARCHAR (MAX)
. Esos fueron los valores predeterminados cuando se hizo esta pregunta. A partir de quizás Visual Studio 2012, el valor predeterminado se cambió para usar MAX
para los 4 de estos tipos de datos. Esto no es necesariamente algo bueno, ya que existe un impacto definitivo en el rendimiento para usar los tipos MAX
frente a los tipos que no son MAX
. Por lo tanto, si no necesita más de 8000 bytes de VARBINARY
o 4000 bytes de NVARCHAR
, entonces querrá anular el valor predeterminado utilizando uno de los siguientes métodos:
-
Puede
ALTER
la definición de función o proceso después de que Visual Studio la genere, y en este caso incluso puede cambiar los tipos de datos (de parámetros de entrada o valores de retorno) para que sean cualquier tamaño comoVARBINARY (100)
oNVARCHAR(50)
. -
Puede usar el decorador
SqlFacet
para indicarle a Visual Studio / SSDT que genere automáticamente las definiciones de función o proceso con la opción de tamaño que prefiera en lugar de la predeterminada. El siguiente ejemplo muestra cómo especificar el tamaño de los parámetros de entrada y el valor de retorno (tenga en cuenta que-1
=MAX
):[return: SqlFacet(MaxSize = -1)] [Microsoft.SqlServer.Server.SqlFunction(Name = "FunctionName")] public static SqlBinary FuncName([SqlFacet(MaxSize = 50)] SqlString InputParam)
Usando cualquiera de estos dos métodos, puede hacer que SqlBinary
o SqlBytes
se asignen a VARBINARY (1 - 8000)
o VARBINARIO (MAX)
. Del mismo modo, puede hacer que SqlString
o SqlChars
se asignen a eithert NVARCHAR (1 - 4000)
o NVARCHAR (MAX)
.
Parece que la respuesta es sí: puede usar ambos varbinary (MAX) devolviendo " SqlBinary " o puede usar SqlBytes como se recomienda anteriormente.