Разный подход для создания столбцов string
create table #temp
(
date datetime,
category varchar(3),
amount money
)
insert into #temp values ('1/1/2012', 'ABC', 1000.00)
insert into #temp values ('2/1/2012', 'DEF', 500.00)
insert into #temp values ('2/1/2012', 'GHI', 800.00)
insert into #temp values ('2/10/2012', 'DEF', 700.00)
insert into #temp values ('3/1/2012', 'ABC', 1100.00)
DECLARE @cols AS NVARCHAR(MAX)='';
DECLARE @query AS NVARCHAR(MAX)='';
SELECT @cols = @cols + QUOTENAME(category) + ',' FROM (select distinct category from #temp ) as tmp
select @cols = substring(@cols, 0, len(@cols)) --trim "," at end
set @query =
'SELECT * from
(
select date, amount, category from #temp
) src
pivot
(
max(amount) for category in (' + @cols + ')
) piv'
execute(@query)
drop table #temp
Результат
date ABC DEF GHI
2012-01-01 00:00:00.000 1000.00 NULL NULL
2012-02-01 00:00:00.000 NULL 500.00 800.00
2012-02-10 00:00:00.000 NULL 700.00 NULL
2012-03-01 00:00:00.000 1100.00 NULL NULL
Кажется, вы не можете использовать метапрограммирование Groovy, чтобы заменить методы классов Java - даже публичные методы - попробуйте выполнить следующие действия в консоли Groovy:
ArrayList.metaClass.remove = { obj ->
throw new Exception('remove')
}
ArrayList.metaClass.remove2 = { obj ->
throw new Exception('remove2')
}
def a = new ArrayList()
a.add('it')
// returns true because the remove method defined by ArrayList is called,
// i.e. our attempt at replacing it above has no effect
assert a.remove('it')
// throws an Exception because ArrayList does not define a method named remove2,
// so the method we add above via the metaClass is invoked
a.remove2('it')
Если вы можете изменить исходный код из MyClass
я либо сделал бы doSomethingCrazyExpensive
защищенным, либо, желательно, реорганизовал его так, чтобы он был более дружественным к тестированию
public class MyClass {
private ClassOfSomeSort property1;
private ClassOfSomeOtherSort property2;
private CrazyExpensive crazyExpensive;
public MyClass(CrazyExpensive crazyExpensive) {
this.crazyExpensive = crazyExpensive;
}
public void init(){
property1 = new ClassOfSomeSort();
property2 = new ClassOfSomeOtherSort();
crazyExpensive.doSomethingCrazyExpensive();
}
}
public interface CrazyExpensive {
public void doSomethingCrazyExpensive();
}
После внесения изменений выше, при тестировании MyClass
вы можете легко создать экземпляр с помощью макета / заглушки CrazyExpensive
.