2011-09-30 37 views
10

Mam UDT CLR, które w znacznym stopniu korzystać z wycenione tabela metod, Ala xml.nodes():Czy jest możliwe utworzenie metod * o wartości * przechowywanych w tabeli w typie zdefiniowanym przez użytkownika SQL CLR?

-- 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) 

chcę coś podobnego do mojego 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) 

Czy ktoś ma jakieś doświadczenia wagowo/to? Każda pomoc będzie bardzo ceniona. Próbowałem kilku rzeczy i wszystkie zawiodły. Szukałem dokumentacji i przykładów i nie znalazłem żadnego.

Tak, wiem, że mógłbym tworzyć UDF o wartościach tabelarycznych, które przyjmują mój UDT jako parametr, ale miałem nadzieję, że zbiorę wszystko wewnątrz jednego typu, w stylu OO.

EDIT

Russell Hart znaleźć the documentation states that table-valued methods are not supported, a stały mój składni do wytworzenia błąd wykonania oczekiwany (patrz niżej).

W VS2010, po utworzeniu nowego UDT, dodałem to na końcu definicji struct:

[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; 
} 

To buduje i wdraża z powodzeniem. Ale potem w SSMS, otrzymujemy błąd wykonania zgodnie z oczekiwaniami (jeżeli nie słowo w słowo):

-- 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. 

Więc wydaje się, że nie jest przecież możliwe. A nawet gdyby było to możliwe, prawdopodobnie nie byłoby to rozsądne, biorąc pod uwagę ograniczenia dotyczące modyfikacji obiektów CLR w SQL Server.

To powiedziawszy, jeśli ktokolwiek zna się na hackach, aby ominąć to konkretne ograniczenie, podniosę odpowiednio nową nagrodę.

Odpowiedz

6

Masz aliasować tabelę, ale nie kolumny. Spróbuj,

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

Zgodnie z dokumentacją, http://msdn.microsoft.com/en-us/library/ms131069(v=SQL.100).aspx#Y4739, powinno to nie na innym błędem wykonawczym dotyczącym nieprawidłowego typu.

Klasa SqlMethodAttribute dziedziczy z klasy SqlFunctionAttribute, więc SqlMethodAttribute dziedziczy pola FillRowMethodName i TableDefinition z SqlFunctionAttribute. Oznacza to, że możliwe jest napisanie metody wycenionej za pomocą tabeli, co nie jest możliwe. Metoda kompiluje i zespół jest wdrażany, ale błąd dotyczący IEnumerable zwracanego typu jest wywoływany w środowisku wykonawczym z następującym komunikatem: "Metoda, właściwość lub pole" w klasie "" w zespole "" ma nieprawidłowy typ zwracania. "

Mogą unikać takiej metody. Jeśli zmienisz zespół za pomocą aktualizacji metod, może to spowodować problemy z danymi w kolumnach UDT. Odpowiednim rozwiązaniem jest posiadanie minimalnego UDT, a następnie oddzielnej klasy metod, które mu towarzyszą. Zapewni to elastyczność i w pełni funkcjonalne metody.

Metoda węzłów xml nie ulegnie zmianie, więc nie podlega tym samym ograniczeniom w zakresie implementacji.

Mam nadzieję, że to pomoże Peterowi i powodzenia.

+0

Dzięki Russ, tak to pomaga. –