2011-09-30 11 views
10

que tienen un UDT CLR que se beneficiaría enormemente de métodos con valores de tabla, ala xml.nodes():¿Es posible crear * métodos * con valores de tabla en un CLR SQL de tipo definido por el usuario?

-- nodes() example, for reference: 
declare @xml xml = '<id>1</id><id>2</id><id>5</id><id>10</id>' 
select c.value('.','int') as id from @xml.nodes('/id') t (c) 

quiero algo similar para mi UDT:

-- would return tuples (1, 4), (1, 5), (1, 6)....(1, 20) 
declare @udt dbo.FancyType = '1.4:20' 
select * from @udt.AsTable() t (c) 

¿Alguien tiene alguna experiencia w/¿esta? Cualquier ayuda sería muy apreciada. He intentado algunas cosas y todas han fallado. He buscado documentación y ejemplos y no encontré ninguno.

Sí, sé que podría crear UDF con valores de tabla que utilicen mi UDT como parámetro, pero esperaba agrupar todo dentro de un solo tipo, estilo OO.

EDITAR

Russell Hart encontró the documentation states that table-valued methods are not supported, y fijó mi sintaxis para producir el error de ejecución esperado (véase más adelante).

En VS2010, después de crear un nuevo UDT, he añadido esto al final de la definición de estructura:

[SqlMethod(FillRowMethodName = "GetTable_FillRow", TableDefinition = "Id INT")] 
public IEnumerable GetTable() 
{ 
    ArrayList resultCollection = new ArrayList(); 
    resultCollection.Add(1); 
    resultCollection.Add(2); 
    resultCollection.Add(3); 
    return resultCollection; 
} 

public static void GetTable_FillRow(object tableResultObj, out SqlInt32 Id) 
{ 
    Id = (int)tableResultObj; 
} 

Esto construye y despliega con éxito. Pero entonces, en SSMS, obtenemos un error de ejecución como se espera (si no palabra por palabra):

-- needed to alias the column in the SELECT clause, rather than after the table alias. 
declare @this dbo.tvm_example = '' 
select t.[Id] as [ID] from @this.GetTable() as [t] 

Msg 2715, Level 16, State 3, Line 2 
Column, parameter, or variable #1: Cannot find data type dbo.tvm_example. 
Parameter or variable '@this' has an invalid data type. 

Por lo tanto, parece que no es posible después de todo. E incluso si fuera posible, probablemente no sería prudente, dadas las restricciones sobre la modificación de objetos CLR en SQL Server.

Dicho esto, si alguien conoce un truco para eludir esta limitación en particular, voy a recaudar una nueva recompensa en consecuencia.

Respuesta

6

Tiene un alias de la tabla pero no de las columnas. Intenta,

declare @this dbo.tvm_example = '' 
select t.[Id] as [ID] from @this.GetTable() as [t] 

Según la documentación, http://msdn.microsoft.com/en-us/library/ms131069(v=SQL.100).aspx#Y4739, esto debe fallar en otro error de ejecución en relación con el tipo incorrecto.

La clase SqlMethodAttribute hereda de la clase SqlFunctionAttribute, por lo SqlMethodAttribute hereda los campos FillRowMethodName y TableDefinition de SqlFunctionAttribute. Esto implica que es posible escribir un método con valores de tabla, que no es el caso. El método se compila y el ensamblaje se despliega, pero se genera un error sobre el tipo de retorno IEnumerable en tiempo de ejecución con el siguiente mensaje: "Método, propiedad o campo '' en la clase '' en ensamblado '' tiene un tipo de devolución no válido.

Es posible que eviten el uso de dicho método. Si modifica el ensamblado con actualizaciones de métodos, esto puede causar problemas a los datos en columnas UDT. Una solución adecuada es tener un UDT mínimo, luego una clase separada de métodos para acompañarlo. Esto asegurará flexibilidad y métodos completos.

El método de los nodos xml no cambiará, por lo que no está sujeto a las mismas limitaciones de implementación.

Espero que esto ayude a Peter y buena suerte.

+0

Gracias Russ, sí que ayuda. –

Cuestiones relacionadas