merge podmnožina cílové tabulky
<p>snažím se pomocí příkazu <code>merge</code> vložit nebo smazat řádky z tabulky, ale chci jen jednat na podmnožině těchto řádků. dokumentace pro <code>merge</code> obsahuje velmi důrazně formulované varování:</p><blockquote> <p>je důležité určit pouze sloupce z cílové tabulky, které se používají pro účely shody. to znamená, určit sloupce z cílové tabulky, které jsou porovnány s odpovídajícím sloupcem zdrojové tabulky. nepokoušejte se zlepšit výkon dotazu odfiltrováním řádků v cílové tabulce v klauzuli on, například zadáním and not target\_table.column\_x = value. pokud tak učiníte, může dojít k neočekávaným a nesprávným výsledkům.</p> </blockquote><p>ale to je přesně to, co se zdá, že musím udělat, aby moje <code>merge</code> fungovala.</p><p>data, která mám, jsou standardní spojovací tabulkou mezi mnoha položkami a kategoriemi (např. které položky jsou zahrnuty do kterých kategorií):</p><pre><code>categoryid itemid   1 1 1 2 1 3 2 1 2 3 3 5 3 6 4 5 </code></pre><p>musím účinně nahradit všechny řádky v určité kategorii novým seznamem položek. můj první pokus o to vypadá takto:</p><pre><code>merge into categoryitem as target using ( select itemid from someexternaldatasource where categoryid = 2 ) as source on source.itemid = target.itemid and target.categoryid = 2 when not matched by target then insert ( categoryid, itemid ) values ( 2, itemid ) when not matched by source and target.categoryid = 2 then delete ; </code></pre><p>to <em>zdá se</em>, že pracuje v mých testech, ale dělám přesně to, co mě msdn výslovně varuje, abych neudělal. to mě znepokojuje, že se později setkám s neočekávanými problémy, ale nevidím žádný jiný způsob, jak můj <code>merge</code> ovlivní pouze řádky se specifickou hodnotou pole (<code>categoryid = 2</code>) a ignorovat řádky z jiných kategorií.</p><p>existuje „správnější“ způsob, jak dosáhnout stejného výsledku? a jaké jsou „neočekávané nebo nesprávné výsledky“, na které mě msdn upozorňuje?</p>
<p>příkaz <code>merge</code> má složitou syntaxi a ještě složitější implementaci, ale v zásadě jde o spojení dvou tabulek, filtrování dolů na řádky, které je třeba změnit (vložit, aktualizovat nebo smazat), a poté provést požadované změny. vzhledem k těmto vzorovým údajům:</p><pre><code>declare @categoryitem as table ( categoryid integer not null, itemid integer not null, primary key (categoryid, itemid), unique (itemid, categoryid) ); declare @datasource as table ( categoryid integer not null, itemid integer not null primary key (categoryid, itemid) ); insert @categoryitem (categoryid, itemid) values (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 5), (3, 6), (4, 5); insert @datasource (categoryid, itemid) values (2, 2); </code></pre><p><strong> cíl </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 2 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 3 ║ ║ 3 ║ 5 ║ ║ 4 ║ 5 ║ ║ 3 ║ 6 ║ ╚════════════╩════════╝ </code></pre><p><strong> zdroj </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>požadovaným výsledkem je nahrazení dat v cíli daty ze zdroje, ale pouze pro <code>categoryid = 2</code>. po výše uvedeném popisu <code>merge</code> bychom měli napsat dotaz, který spojuje zdroj a cíl pouze na klíče, a filtrovat řádky pouze v klauzulích <code>when</code>:</p><pre><code>merge into @categoryitem as target using @datasource as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by source and target.categoryid = 2 then delete when not matched by target and source.categoryid = 2 then insert (categoryid, itemid) values (categoryid, itemid) output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>to dává následující výsledky:</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 2 ║ ║ 3 ║ 5 ║ ║ 3 ║ 6 ║ ║ 4 ║ 5 ║ ╚════════════╩════════╝ </code></pre><p>realizační plán je: <img src="https://i.stack.imgur.com/fovhu.jpg" alt="merge plan"></p><p>všimněte si, že jsou obě tabulky plně naskenovány. můžeme to považovat za neefektivní, protože pouze řádky, kde <code>categoryid = 2</code> bude ovlivněno v cílové tabulce. zde přicházejí varování v books online. jeden chybný pokus o optimalizaci, aby se dotkl pouze nezbytných řádků v cíli, je:</p><pre><code>merge into @categoryitem as target using ( select categoryid, itemid from @datasource as ds where categoryid = 2 ) as source on source.itemid = target.itemid and target.categoryid = 2 when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>logika v klauzuli <code>on</code> je použita jako součást spojení. v tomto případě je spojení úplným vnějším spojením (viz <a href="http://technet.microsoft.com/en-us/library/bb522522%28v=sql.105%29.aspx">tento záznam books online</a> proč). použití kontroly kategorie 2 na cílových řádcích jako součásti vnějšího spojení nakonec povede k odstranění řádků s jinou hodnotou (protože neodpovídají zdroji):</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 1 ║ 1 ║ ║ delete ║ 1 ║ 2 ║ ║ delete ║ 1 ║ 3 ║ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ║ delete ║ 3 ║ 5 ║ ║ delete ║ 3 ║ 6 ║ ║ delete ║ 4 ║ 5 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>kořenová příčina je ze stejného důvodu, proč se predikáty chovají v klauzuli vnější spojení <code>on</code> odlišně, než když jsou specifikovány v klauzuli <code>where</code>. syntaxe <code>merge</code> (a implementace spojení v závislosti na zadaných klauzulích) jen ztěžují vidět, že tomu tak je.</p><p> <a href="http://technet.microsoft.com/en-us/library/bb510625%28v=sql.105%29.aspx">navádění v books online</a> (rozšířeno v položce <a href="http://technet.microsoft.com/en-us/library/cc879317%28v=sql.105%29.aspx">optimizing performance</a> ) nabízí navádění, které zajistí, že správná sémantika je vyjádřena pomocí syntaxe <code>merge</code>, aniž by uživatel nutně musel muset pochopit všechny podrobnosti implementace nebo zohlednit způsoby, kterými by optimalizátor mohl legitimně přeskupit věci z důvodů efektivnosti provádění.</p><p>dokumentace nabízí tři možné způsoby implementace časného filtrování:</p><p><strong> zadání podmínky filtrování v klauzuli <code>when</code> </strong> zaručuje správné výsledky, ale může znamenat, že více řádků je čteno a zpracováno ze zdroje a cíle tabulky, než je nezbytně nutné (viz první příklad).</p><p><strong> aktualizace prostřednictvím zobrazení </strong>, která obsahuje podmínku filtrování, také zaručuje správné výsledky (protože změněné řádky musí být přístupné pro aktualizaci prostřednictvím zobrazení), ale vyžaduje to vyhrazené zobrazení, které splňuje liché podmínky pro aktualizaci zobrazení.</p><p><strong> použití společného výrazu tabulky </strong> přináší podobné riziko při přidávání predikátů k klauzuli <code>on</code>, ale z poněkud odlišných důvodů. v mnoha případech to bude bezpečné, ale vyžaduje to odbornou analýzu prováděcího plánu, aby se to potvrdilo (a rozsáhlé praktické testování). například:</p><pre><code>with target as ( select * from @categoryitem where categoryid = 2 ) merge into target using ( select categoryid, itemid from @datasource where categoryid = 2 ) as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>výsledkem jsou správné výsledky (neopakované) s optimálnějším plánem:</p><p><img src="https://i.stack.imgur.com/tazmk.jpg" alt="merge plan 2"></p><p>plán čte pouze řádky pro kategorii 2 z cílové tabulky. to může být důležitým hlediskem výkonu, pokud je cílová tabulka velká, ale je příliš snadné tuto chybu získat pomocí syntaxe <code>merge</code>.</p><p>někdy je snazší zapsat <code>merge</code> jako samostatné operace dml. tento přístup může dokonce <strong> vést lépe </strong> než jediný <code>merge</code>, což je skutečnost, která lidi často překvapuje.</p><pre><code>delete ci from @categoryitem as ci where ci.categoryid = 2 and not exists ( select 1 from @datasource as ds where ds.itemid = ci.itemid and ds.categoryid = ci.categoryid ); insert @categoryitem select ds.categoryid, ds.itemid from @datasource as ds where ds.categoryid = 2; </code></pre>
Pokud se ti nechce do maker, tak prohoď řádky a sloupce a použij standardní řazení.[http://www.chip.cz/clanky/tipy-triky/aplikac...](http://www.chip.cz/clanky/tipy-triky/aplikace/2011/07/prevraceni-tabulky-2013-zamena-radku-a-sloupcu) Takže jste se ptali, jak zvládnout práci na násobku „úkolů“ najednou, ne? S výjimkou větvení.


Můžete mít více checkouts ze zdroje na lokálním počítači, suffixing název adresáře s názvem lístku, na kterém pracujete. Jen se ujistěte, aby se změny ve správném adresáři, v závislosti na úkolu ...


Směšování více úkolů v jedné pracovní kopii / commit může být velmi matoucí, zvláště pokud někdo potřebuje, aby svou práci zkontrolovat později. Č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>po nějaké zkoušce a omylu to je to, co je potřeba, aby to fungovalo ...</p><pre><code> $cat\_args = array('orderby' =&gt; 'count'); $cat\_args['title\_li'] = ''; $cat\_args['exclude\_tree'] = 1; $cat\_args['exclude'] = 1; $cat\_args['depth'] = 1; wp\_list\_categories(apply\_filters('widget\_categories\_args', $cat\_args)); </code></pre> zkopíruješ zdrojovou buňku a u cílové dáš vložit propojení Tvůj kód nehodlám číst, takže jen obecně. Na začátku před tím než budeš data řadit, tak si udělej jejich kopii. Pak si data seřaď a máš co jsi chtěl. V té kopii máš původní neseřazená data v původním pořadí. <p>pravděpodobně se dostáváte do radostí mysql myisam engine ...</p><p>v rámci mysql (nebo phpmyadmin) použijte příkazy repair table xyz znovu, opakovaně, na každé z vašich tabulek (nebo spíše tabulek souvisejících s vašimi podmínkami, protože to jsou ty, které znějí zkaženě), aby se zjistilo, zda to nic nevyřeší.</p><p>pokud selžou, existuje několik zdokumentovaných řešení:</p><p> <a href="http://www.google.com/search?q=recover+a+corrupt+mysql+database">http://www.google.com/search?q=recover+a+corrupt+mysql+database</a> </p><p>jakmile jsou věci obnoveny, spusťte příkazy optimalizovat tabulku xyz na každé tabulce a poté změňte motor databáze a každou tabulku, aby byla použita innodb. innodb poněkud neuspořádá katalog (zejména pokud upustíte databázi nebo velké tabulky), ale - pokud je kompatibilní s acid - je to o dost méně náchylné k chybám než myisam.</p> Jeden klik na jakoukoli buňku, sloupek, či řádek. Poté zmáčknete "vyhledat" (Ctrl + F). V políčku "Najít" napíšete pouze tečku.Ve stejném okně kliknete na záložku "Nahradit" a do políčka "Nahradit" napíšete pouze čárku.Pak se jen rozhodnete mezi tlačítkem "Nahradit vše" a "Nahradit" - "Nahradit vše" vám nahradí každou tečku v daném listu čárkou, zatímco "Nahradit" vám udělá to samé, ale jen v označené lokaci (buňka, řádek, sloupec). Poté, co je nahrazena tečka čárkou se již číslo chová jako normální číslo. Toť vše. Hmm, zni to dost zmatene. Nechapu, proc by tabulka z Wordu nesla zkopcit?! A ta druha tabulka v Excelu je zase co? Tak je v Excelu nebo ve Wordu? Neni to kontingencni tabulka? Zkuste pomalu a srozumitelne popsat o co presne jde a uvedomte si, ze jste jedina kdo vi vsechny informace a musite je predat. K dispozici je celá řada možností pro kontrolu této.


-MD zobrazí seznam souborů, -MMD vypíše non-systémové soubory jako vedlejší účinky kompilace


-M, -mm bude generovat seznamy namísto kompilace.


-MQ, -MG, -MP a -MT generování makefile cílových fragmentů. -mf umožňuje zadat jméno výstupního souboru.