SSRS 2012- Vyhněte vykreslit sestavy, když nejsou k dispozici žádné řádky pro návrat




Já jsem přemýšlel, jestli existuje nějaký možný způsob, jak zabránit zprávu spustit nebo spustit, pokud nejsou k dispozici žádné řádky, které mohou být vráceny do SQL Server Reporting Services 2012. Jinými slovy, existuje v návrhu rozpočtu žádné řádky, které mají být vráceny. 


Budeme se snaží snížit množství e-mailů odeslaných z zabráněním zprávy z běhu, když tam nejsou nic pro zobrazení.


Moc děkuji


Marcus
Často toto je provedeno pomocí [„Data Driven odběry“](https://msdn.microsoft.com/en-us/library/ms169673.aspx) , ale tato funkce je k dispozici pouze v některých SQL vydáních: Enterprise a Business Intelligence, ale ne v normě.


Takže existuje celá řada kreativních řešení. Ale nemám rád žádné z nich, a všechny vyžadují spravedlivý trochu práce mimo SSRS.


Mezi řešení, které jsem viděl, patří: Vytvoření odběr a potom zakázání nebo povolení SQL úlohu, kterou odešle předplatné (identifikovatelné podle GUID).


Vytvořte si .NET obálky exe zvládnout odeslání e-mailu. Je možné spustit dotaz nejprve zjistit, kolik se vrací řádky, a pak v případě potřeby generovat zprávu a zahrnout do e-mailu.
<p>pro zálohování jedné databáze z příkazového řádku použijte <a href="https://msdn.microsoft.com/en-us/library/ms162806.aspx">osql</a> nebo <a href="https://msdn.microsoft.com/en-us/library/ms162773.aspx">sqlcmd</a> .</p><pre><code>"c:\program files\microsoft sql server\90\tools\binn\osql.exe" -e -q "backup database mydatabase to disk='c:\tmp\db.bak' with format" </code></pre><p>budete také chtít přečíst dokumentaci o <a href="https://msdn.microsoft.com/en-us/library/ms186865.aspx">backup</a> a <a href="https://msdn.microsoft.com/en-us/library/ms190372.aspx">obnovit</a> a <a href="https://msdn.microsoft.com/en-us/library/ms187048.aspx">obecných postupech</a> .</p> <h2>v ideálním případě žádné</h2><p>ale to není vždy možné. nemohu vám dát tvrdá čísla jako 20% nebo 10 řádků, což je subjektivní do té míry, že na ni nelze odpovědět. dokážu popsat, jak používám návrhové vzory a okolnosti, které je vyžadují mírně ohýbat.</p><p>podle mého názoru je to zcela na účelu aplikace. vytváření jednoduchých rest api, které chcete zveřejnit? zapomněli jste na čisté oddělení nebo dokonce na vzor. můžete vypálit funkční verzi za hodinu. budování něčeho většího? pravděpodobně nejlepší na tom pracovat.</p><p>cílem je budování individuálně obsažených systémů. pokud začnete psát obchodní logiku, která je specifická pro to, jak dva systémy interagují, je to problém. aniž bych se na to dál díval, nemohu vyjádřit názor.</p><p>designové vzory jsou formy, některé je rádi striktně dodržují na základě principu a dobře napsaného kódu. přísné dodržování vzoru vám pravděpodobně nedá <em> špatný </em> kód, ale může to zabrat více času a způsobit, že budete psát <em> mnohem více </em> kód.</p><p>designové vzory jsou flexibilní, upravte je tak, aby vyhovovaly <em> vašim </em> potřebám. ohněte je příliš mnoho a oni se ale zlomí. <strong>víte, co potřebujete</strong> a vyberte vzorec vzoru, který je k tomu nejblíže.</p> <p>ve skriptech shell není důležité žádné odsazení.</p><p>mírně méně flippant odpověď:</p><ul> <li>vyberte si ve svém týmu standard, se kterým můžete pracovat, zjednodušit věci.</li> <li>použijte něco, co editor usnadňuje, takže nemusíte bojovat, abyste se drželi standardu.</li> </ul> Nic takového neexistuje. Soubor - dokument je pouze pasivní záležitost a neumožňuje řídit přístup v závislosti na čase. Součástí dokumentu by musel být nějaký aktivní program, který by ten přístup v závislosti na čase uměl řídit. Takže nejjednodušší opravdu bude rozeslat heslo až v době, kdy má být čtení umožněno. <p>v ssms musíte změnit některé možnosti:</p><p>nástroje - možnosti - výsledky dotazu - sql server - výsledky do mřížky (nebo textu) -&gt; <strong>při kopírování nebo ukládání výsledků uveďte záhlaví sloupců</strong>.</p><p>změněná nastavení se použijí na nová, ale ne existující okna dotazů.</p> Vestavěný, nic. Ale psát něco sám je snadné.


Zkuste má proces, který dotazuje svůj katalog zpráv pro ty, které jsou starší než půl hodiny (nebo tak nějak). Dalo by se dokonce připojit k ReportServerTempDB aby zjistili, zda mají stále aktivní relace (v takovém případě je budete ignorovat trochu déle).


Poté, co jste je našli, je to snadné chytit, které pomocí rozhraní webových služeb a jejich odstranění z katalogu.


Ale ... Já bych vlastně se podívat na lepší způsob, jak poskytnout vlastní filtr, pomocí kódu. Jistě byste mohli poskytnout filtr jako parametr, a použít kód VB v rámci zprávy převést to, co uživatel zadá do něčeho, který by mohl být vyhodnocen pro každý řádek.


Okrást <p>protože ostatní odpovědi již naznačují, sql server může nebo nemusí explicitně zajistit, že řádky jsou seřazeny v pořadí seskupených indexů před <code>insert</code>.</p><p>to závisí na tom, zda má klastrovaný indexový operátor v plánu sadu vlastností <code>dmlrequestsort</code> (což zase závisí na odhadovaném počtu řádků, které jsou vloženy).</p><p>pokud zjistíte, že sql server to z jakéhokoli důvodu podceňuje, můžete mít prospěch z přidání explicitního <code>order by</code> k dotazu <code>select</code> k minimalizaci rozdělení stránek a následné fragmentaci z operace <code>insert</code></p><p><strong> příklad: </strong></p><pre><code>use tempdb; go create table t(n int primary key,filler char(2000)) create table t2(n int primary key,filler char(2000)) go declare @t table (u uniqueidentifier primary key default newid(),n int) insert into @t(n) select number from master..spt\_values where type = 'p' and number between 0 and 499 /*estimated row count wrong as inserting from table variable*/ insert into t(n) select t1.n*1000 + t2.n from @t t1, @t t2 /*same operation using explicit sort*/ insert into t2(n) select t1.n*1000 + t2.n from @t t1, @t t2 order by t1.n*1000 + t2.n select avg\_fragmentation\_in\_percent, fragment\_count, page\_count, avg\_page\_space\_used\_in\_percent, record\_count from sys.dm\_db\_index\_physical\_stats(2, object\_id('t'), null, null, 'detailed') ; select avg\_fragmentation\_in\_percent, fragment\_count, page\_count, avg\_page\_space\_used\_in\_percent, record\_count from sys.dm\_db\_index\_physical\_stats(2, object\_id('t2'), null, null, 'detailed') ; </code></pre><p>ukazuje, že <code>t</code> je masivně roztříštěný</p><pre><code>avg\_fragmentation\_in\_percent fragment\_count page\_count avg\_page\_space\_used\_in\_percent record\_count      99.3116118225536 92535 92535 67.1668272794663 250000 99.5 200 200 74.2868173956017 92535 0 1 1 32.0978502594514 200 </code></pre><p>ale pro <code>t2</code> fragmentace je minimální</p><pre><code>avg\_fragmentation\_in\_percent fragment\_count page\_count avg\_page\_space\_used\_in\_percent record\_count      0.376 262 62500 99.456387447492 250000 2.1551724137931 232 232 43.2438349394613 62500 0 1 1 37.2374598468001 232 </code></pre><p>naopak někdy budete chtít donutit sql server, aby podceňoval počet řádků, když víte, že data jsou již předem roztříděna a chcete zabránit zbytečnému třídění. jedním z pozoruhodných příkladů je vložení velkého počtu řádků do tabulky pomocí seskupeného indexového klíče <code>newsequentialid</code>. <a href="https://connect.microsoft.com/sqlserver/feedback/details/668540/unnecessary-sort-operation-for-insert-into-clustered-index-with-newsequentialid-key">ve verzích sql serveru před denali sql server přidává zbytečnou a potenciálně nákladnou operaci řazení</a> . tomu lze zabránit</p><pre><code>declare @var int =2147483647 insert into foo select top (@var) * from bar </code></pre><p>sql server poté odhadne, že bude vloženo 100 řádků bez ohledu na velikost <code>bar</code>, která je pod prahem, při kterém je do plánu přidáno řazení. jak je však uvedeno v poznámkách níže, znamená to, že vložka bohužel nebude moci využít výhody minimálního protokolování.</p> <h2>souhrn</h2><p>nechte propojený server dělat co nejvíce.<br> je <em> nemožné </em> pro sql server optimalizovat dotaz na propojeném serveru, dokonce i na jiném serveru sql</p><h2>dlouho</h2><p>klíčovým faktorem je <em> kde </em> je dotaz spuštěn.</p><p>v tomto případě se jedná o triviální výběr, takže všechny řádky z tabulky budou odeslány po drátu. nezáleží na tom.</p><p>když přidáte připojení a kde, pak na tom může záležet. chcete, aby sql server umožnil propojenému serveru provést co největší filtrování, aby se zmenšila velikost dat přicházejících po síti.</p><p>například druhý případ by zde měl být efektivnější.</p><pre><code>select * from openquery(&lt;linked server&gt;, 'select &lt;column list&gt; from mytable') t1 join somelocaltable t2 on ... where t1.foo = 'bar' select * from openquery(&lt;linked server&gt;, 'select &lt;column list&gt; from mytable where foo = ''bar''') join somelocaltable t2 on ... </code></pre><p>omezení openquery je v tom, že nemůžete parametrizovat: proto potřebujete dynamický sql, abyste mohli přidat klauzule where atd.</p><p>výkon propojených serverů může být ovlivněn <a href="http://msdn.microsoft.com/en-us/library/ms178532.aspx"><code>sp\_serveroption</code></a> . nastavení <code>collation compatible</code> říká vše</p><blockquote> <p>pokud je tato možnost nastavena na true, sql server předpokládá, že všechny znaky na propojeném serveru jsou kompatibilní s místním serverem, pokud jde o znakovou sadu a pořadí řazení (nebo pořadí řazení). to umožňuje serveru sql server odesílat porovnání sloupců znaků zprostředkovateli. pokud tato možnost není nastavena, sql server vždy vyhodnocuje porovnání na sloupcích znaků místně.</p> </blockquote><p>to znamená, zkuste nenechat sql server zpracovat data místně.</p><p>poznámka: na mé <code>foo = 'bar'</code> druhý příklad výše je filtr odeslán na propojený server, protože je to pouze řetězcová konstanta na sql server. skutečná klauzule where v prvním příkladu může nebo nemusí být zaslána vzdáleně.</p><p>nakonec jsem také zjistil, že rozložení dat do dočasné tabulky a jejich připojení k místním tabulkám je často lepší než připojení přímo k openquery.</p> Nejlepší vysvětlení jsem viděl, je v kapitole 7 volných [Základy programování e-knihy](http://codebetter.com/karlseguin/2008/06/25/foundations-of-programming-ebook/) .


Zjednodušeně řečeno, v **.NET** dochází k nevracení paměti při odkazované objekty kořeny, a proto nemůže být uvolněna. K tomu dochází náhodně, když se držet na referencí mimo zamýšlený rozsah.


Budete vědět, že máte úniky, když začnete dostat OutOfMemoryExceptions nebo vaše využití paměti stoupá rámec toho, co byste očekávali ( **PerfMon** má pěkné čítače paměti).


Pochopení **.NET** model paměti je, je nejlepší způsob, jak se vyhnout to. Konkrétně pochopení toho, jak garbage collector funguje a jak reference práce - opět odkazuji na kapitolu 7 e-knihy. Také mějte na paměti společných úskalí, pravděpodobně nejvíce obyčejné jsoucí události. Pokud objekt je registrována k události na objekt **B** , pak objekt **A** bude držet kolem, dokud objekt **B** zmizí, protože **B** uchovává odkaz . Řešením je zrušení registrace na akce, když budete hotovi.


Samozřejmě, dobrý profil paměť vám umožní vidět vaše objektů grafy a prozkoumat hnízdění / odkazování svých objektů, které mají zjistit, kde reference přicházejí a co kořenový objekt je zodpovědný ( [red-gate mravenci profil](http://www.red-gate.com/products/ants_memory_profiler/index.htm) , JetBrains dotMemory, [memprofiler](http://memprofiler.com/) jsou opravdu dobré volby, nebo můžete použít pouze text **WinDbg** a **SOS** , ale já bych důrazně doporučujeme obchodní / vizuální produkt, pokud jste opravdový guru).


Věřím, že neřízený kód je předmětem jeho typické úniky paměti, že kromě sdílené odkazy jsou řízeny garbage collector. Možná se mýlím o tomto posledním bodě. <p>použití sql server profiler (nástroj gui) ke sledování produkčního serveru není dobrý nápad. ale záleží to na zatížení. namísto toho použijte trasování sql na straně serveru (viz <a href="http://msdn.microsoft.com/en-us/library/ms188662%28v=sql.100%29.aspx">sp\_trace\_xxx</a> procedury). také jsem našel články:</p><p> <a href="http://sqlblog.com/blogs/linchi\_shea/archive/2007/08/01/trace-profiler-test.aspx">dopad na výkon: trailer profiler vs. tracing sql na straně server</a> ,</p><p> <a href="http://vyaskn.tripod.com/server\_side\_tracing\_in\_sql\_server.htm">automatizace trasování na straně serveru na serveru sql</a> </p><p> <a href="http://weblogs.sqlteam.com/dang/archive/2007/12/16/avoid-causing-problems-with-profiler.aspx">vyhněte se příčinám problémů s profilerem</a> </p><p>možná to bude zajímavé a užitečné.</p><p> <a href="http://msdn.microsoft.com/en-us/library/ms187023.aspx">kniha online</a> říká:</p><ul> <li>spusťte profiler na dálku místo přímo na serveru</li> <li>vyhněte se zahrnutí událostí, které se vyskytují často (např. zámek: získané), pokud to není nezbytně nutné</li> <li>zahrnout pouze potřebné třídy událostí</li> <li>určete omezující filtry pro snížení počtu událostí</li> <li>vyhněte se nadbytečným datům (např. sql: batchstarting a sql: batchcompleted)</li> <li>vyhněte se běhu velkých stop s profilerem; místo toho zvažte serverové sql trasování</li> <li>omezte velikost trasovacího souboru na straně serveru a spravujte využití místa</li> </ul>