Хотел сделать простой интерфейс для запуска отчётов при помощи самого SSRS, где видны все отчёты, а не только те, о которых уже знают приложения.
Скорее для поддержки или разработчиков, чем для конечных пользователей.
Закончить пока не довелось, сделано давно. Не завершено, как-то работает, но подтормаживает.
Может кому пригодится.
.rdl файл примитивен:
группа по полю ItemId
в ней сортировка по Sequence
первоначальная видимость по условию =iif(Level()=0,false,true)
показ(разворачивание дерева) переключается по Name
рекурсивный предок ParentId
наружу 2 поля Name и Description
для Name установлен Padding=25*Level()&"pt"; 2pt; 2pt; 2pt
и Action Go to URL по полю URL
SQL запрос:
поддерживаются подключение одного и того же отчёта в разные ветки
попытка поддержки отчётов, выложенных из разных версий sql
не учитываются права доступа, т.е. все отчёты видны всем
параметры:
@sServer название сервера для вызова отчёта через URL
@sUserName имя sql пользователя, если нужен показ последних вызванных
@bUseRecent показ последних вызванных или всех
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271.
declare @sServer varchar ( max )
,@sUserName sysname
,@bUseRecent bit= 0
----------
create table #Recent
( ItemId uniqueidentifier )
----------
if @bUseRecent= 1
insert
#Recent ( ItemId )
select
ItemId= ReportId
from
ReportServer.dbo.ExecutionLogStorage
where
UserName= @sUserName
group by
ReportId
----------
declare @gRoot uniqueidentifier
,@gRoot1 uniqueidentifier
,@sDelimeter varchar ( 36 )
,@sURL varchar ( max )
----------
select @sDelimeter= 'DB298F1C65AF4016A4931061BF22A2EE'
,@sURL= @sServer+ '/ReportServer/Pages/ReportViewer.aspx?'
----------
----------
select
@gRoot= ItemId
from
ReportServer.dbo.Catalog
where
Path= '' -- clustered index
and ParentID is null
and Type= 1
----------
select
@gRoot1= ItemId
from
ReportServer.dbo.Catalog
where
ParentID= @gRoot
and Type= 1
----------
select
c.ItemID
,c.Type
,c.Path
-- ,c.Name
,ParentID= nullif ( c.ParentID , @gRoot1 )
,c.LinkSourceID
,Content0= convert ( varchar ( max ) , convert ( varbinary ( max ) , c.Content ) )
,Content= convert ( xml , null )
,Sequence= row_number() over ( order by c.Path )
into
#Catalog
from
ReportServer.dbo.Catalog c
left join #Recent r on
r.ItemId= c.ItemID
where
c.Type in ( 1, 2, 4 )
and c.ItemID not in ( @gRoot, @gRoot1 )
and ( @bUseRecent= 0
or r.ItemId is not null
or c.Type= 1 )
----------
;with cte as
( select
c.ItemId
,c.ParentId
from
#Catalog c
left join #Catalog p on
p.ItemID= c.ParentID
and p.Type= 1
where
c.Type in ( 2, 4 )
union all
select
p.ItemID
,p.ParentID
from
cte
,#Catalog p
where
p.ItemID= cte.ParentId
)
delete
c
from
#Catalog c
left join cte on
cte.ItemID= c.ItemID
where
cte.ItemID is null
----------
update -- пытаемся исключить разный xmlnamespace, для единой обработки
#Catalog
set
Content= convert ( xml , stuff ( Content0 , charindex ( ' xmlns="' , Content0 )+ len ( ' xmlns="' ) , charindex ( '"' , Content0 , charindex ( ' xmlns="' , Content0 )+ len ( ' xmlns="' ) )- charindex ( ' xmlns="' , Content0 )- len ( ' xmlns="' ) , '' ) )
where
Content0 is not null
----------
--;with xmlnamespaces -- избавились от деклараций, т.к. могут быть одновременно отчёты с декларациями разных версий SSRS
select
ItemID
,ParentId
,Path
-- ,Name
,Parameters= case HasParameter
when 0 then 'без параметров'
else '•'
+ convert ( varchar ( 10 ) , Sequence1 )
+ '-'
+ Parameter
+ ' {'
+ case MultiValue
when 1 then case DataType
when 'Boolean' then 'несколько да/нет'
when 'DateTime' then 'даты'
when 'Integer' then 'числа'
when 'Float' then 'числа'
when 'String' then 'строки'
else 'неизвестные'
end
else case DataType
when 'Boolean' then 'да/нет'
when 'DateTime' then 'дата'
when 'Integer' then 'число'
when 'Float' then 'число'
when 'String' then 'строка'
else 'неизвестное'
end
end
+ case HasList
when 0 then ''
else ' из '
+ case HasDataset
when 1 then 'базы'
else 'списка'
end
end
+ '}'
end
,Sequence
into
#withparams
from
( select
ItemID
,ParentId
,Path
-- ,Name
,Parameter= t.x.value ( './Prompt[1]' , 'varchar(256)' )
,HasParameter= case
when t.x is null then 0
else 1
end
,DataType= t.x.value ( './DataType[1]' , 'varchar(16)' )
,MultiValue= isnull ( t.x.value ( './MultiValue[1]' , 'bit' ) , 0 )
--,DatasetName= t.x.value ( './ValidValues[1]/DataSetReference[1]/DataSetName[1]' , 'varchar(256)' )
,HasDataset= case
when t.x.value ( './ValidValues[1]/DataSetReference[1]/DataSetName[1]' , 'varchar(256)' ) is null then 0
else 1
end
,HasList= case convert ( varchar ( max ) , t.x.query ( './ValidValues[1]' ) )
when '' then 0
else 1
end
,Sequence1= t.x.value ( 'for $s in . return count(../*[.<<$s])+1' , 'integer' )
,Sequence
from
#Catalog
outer apply content.nodes ( '/Report/ReportParameters/ReportParameter' ) t ( x )
where
Type= 2 ) t
----------
-- учитываем и ссылки на отчёты, имеющие то же тело, но другое название
insert
#withparams ( ItemID, ParentId, Path, /*Name, */Parameters, Sequence )
select
c.ItemID
,c.ParentId
,c.Path
-- ,c.Name
,w.Parameters
,c.Sequence
from
#Catalog c
,#withparams w
where
c.Type= 4
and w.ItemID= c.LinkSourceID
----------
select
t.ItemId
,t.ParentId
-- ,t.Path
,cc.Name
-- ,t.Parameters
,Description= isnull ( cc.Description+ ' ' , '' )+ t.Parameters
,t.Sequence
,t.URL
from
( select
ItemId
,ParentId
,Path
-- ,Name
,Parameters= left ( Parameters , len ( Parameters )- 1 )
,Sequence
,URL= @sURL+ Path+ '&rs:Command=Render'+ case
when Path like '%/HTML4.0/%' then '&rs:Format=HTML4.0'
when Path like '%/MHTML/%' then '&rs:Format=MHTML'
when Path like '%/IMAGE/%' then '&rs:Format=IMAGE'
when Path like '%/EXCEL/%' then '&rs:Format=EXCEL'
when Path like '%/EXCELOPENXML/%' then '&rs:Format=EXCELOPENXML'
when Path like '%/WORD/%' then '&rs:Format=WORD'
when Path like '%/CSV/%' then '&rs:Format=CSV'
when Path like '%/PDF/%' then '&rs:Format=PDF'
when Path like '%/XML/%' then '&rs:Format=XML'
when Path like '%/NULL/%' then '&rs:Format=NULL'
else ''
end
from
( select
ItemId
,ParentId
,Path
-- ,Name
,Parameters= replace ( replace ( ( select
[data()]= Parameters+ @sDelimeter
from
#withparams
where
ItemId= t.ItemId
for
xml path ( '' ) ), @sDelimeter+ ' ', ',' ), @sDelimeter, ',' )
,Sequence
from
#withparams t
group by
ItemId
,ParentId
,Path
-- ,Name
,Sequence ) t
union all
select
ItemId
,ParentId
,Path
-- ,Name
,null
,Sequence
,URL= null
from
#Catalog
where
Type= 1 ) t
inner join ReportServer.dbo.Catalog cc on
cc.Path= t.Path
order by
t.Sequence
----------
drop table
#Catalog
,#withparams
,#Recent
|