Mówisz:
We want to highlight the parameters that have changed since the last revision.
Oznacza to, że chcesz, aby wyświetlacz (lub raport) wyróżniał zmienione parametry.
Jeśli i tak zamierzasz pokazać wszystkie parametry, znacznie łatwiej byłoby to zrobić programowo w interfejsie użytkownika. Byłby to znacznie prostszy problem w języku programowania. Niestety, nie wiedząc, jaki jest Twój frontend, nie mogę dać Ci konkretnych zaleceń.
Jeśli naprawdę nie możesz tego zrobić w interfejsie użytkownika, ale musisz otrzymać te informacje w zapytaniu z bazy danych (mówiłeś „tylko SQL”), musisz określić format, w którym chcesz uzyskać dane. jednokolumnowa lista kolumn, które zmieniły się między dwoma rekordami? Lista kolumn z flagą wskazującą, które kolumny uległy zmianie, a które nie?
Ale oto jeden sposób, który zadziała, chociaż w trakcie konwertuje wszystkie pola na nvarchary, zanim dokona porównania:
- Użyj techniki opisanej tutaj (zastrzeżenie:to mój blog), aby przekształcić swoje rekordy w pary identyfikator-nazwa-wartość.
-
Połącz wynikowy zestaw danych ze sobą na ID, aby móc porównać wartości i wydrukować te, które uległy zmianie:
with A as ( -- We're going to return the product ID, plus an XML version of the -- entire record. select ID , ( Select * from myTable where ID = pp.ID for xml auto, type) as X from myTable pp ) , B as ( -- We're going to run an Xml query against the XML field, and transform it -- into a series of name-value pairs. But X2 will still be a single XML -- field, associated with this ID. select Id , X.query( 'for $f in myTable/@* return <data name="{ local-name($f) }" value="{ data($f) }" /> ') as X2 from A ) , C as ( -- We're going to run the Nodes function against the X2 field, splitting -- our list of "data" elements into individual nodes. We will then use -- the Value function to extract the name and value. select B.ID as ID , norm.data.value('@name', 'nvarchar(max)') as Name , norm.data.value('@value', 'nvarchar(max)') as Value from B cross apply B.X2.nodes('/myTable') as norm(data)) -- Select our results. select * from ( select * from C where ID = 123) C1 full outer join ( select * from C where ID = 345) C2 on C1.Name = c2.Name where c1.Value <> c2.Value or not (c1.Value is null and c2.Value is null)