Mi a történik akkor,
ha egy tábla rekordjait rangsorolnám, és ezt a rangsort rögzíteném is a tábla
egy új
oszlopában? Mondjuk így:
UPDATE Buildings SET nRank = ROW_NUMBER() OVER (ORDERBY nHeight);
Ez történik:
Windowed functions can only appear in
the SELECT or ORDER BY clauses.
Szóval csak SELECT vagy ORDER BY. Szerencsére ez nem olyan
nagy gond. Használhatunk CTE-t, beágyazott query-t vagy view-t, és már
teljesítettük is a fenti megkötést. Hogy pontosan hogyan, az ebből a
script-sorból kiderül. A CTE-s verziót be is kopizom ide (szerintem ez a
legelegánsabb).
WITH Ranking AS
(
SELECT
nRank
,ROW_NUMBER() OVER (ORDERBY nHeight) AS nComputedRank
FROM
Buildings
)
UPDATE
Ranking
SET
nRank = nComputedRank;
Nagy rekordszám esetén érdemes elgondolkodni egy indexelt
temp tábla használatán. A lemezre írásnak ugyan van költsége, de lehet, hogy
ezt az indexek miatt bőven behozzuk az update-nél.
Hegedűs Miklós kollégám - miután az SSIS a kezei közt lehelte ki a lelkét egy pakk futtatása közben -, észrevette, hogy az SQL Server-en, az SSIS után beragadt session a rejtélyes -2-es azonosítót kapta. Ezt sajnos a KILL parancs nem tudja kezelni, hibával elszáll:
Msg 6101, Level 16, State 1, Line 1 Process ID -2 is not a valid process ID. Choose a number between 1 and 2048. Kis nyomozás után Miki a megoldást is megtalálta Utsab Chattopadhyay blogján, a CONSULTDBA-n. A -2 az elárvult MSDTC session-öknek dedikált azonosító. Ha a session-t kézzel kell lezárnunk, használhatjuk a KILL-t, ami egy SPID-et, vagy egy UOW (Unit Of Work) azonosítót vár paraméterként. Mivel az előbbi csak 1 és 2048 közé eshet, keressünk egy UOW id-t. A CONSULTDBA szerint így:
SELECT req_transactionUOW FROM master..syslockinfo WHERE req_spid = -2;
Mivel a syslockinfo egy igen régi darab, és a Microsoft azzal fenyeget, hogy a következő SQL Server verzióban már meg se találjuk, én inkább a sys.dm_tran_locks hívását javaslom:
SELECT request_owner_guid FROM master.sys.dm_tran_locks WHERE request_session_id = -2;
Mindkét select egy guid-ot ad vissza, amivel a KILL már működni fog.
Az Addictive Measures blogon találtam
nemrég egy hasznos T-SQL szkriptet,
ami kilistázza az MSDB alá telepített SSIS csomagokat. Hasznos cucc, rajtam
viszont egyre jobban elharapózik a PowerShell mánia (bárcsak időm is lenne rá),
ezért kicsit utánajártam, vajon nem lehet ezt összehozni PS-sel is? Hát persze
hogy de :)
A GetDtsServerPackageInfos
eljárásnak egy szerver és egy mappa nevét kell megadnunk, és már ontja is az
információkat. A szerver azonosításánál pontos nevet, vagy ˝.˝-t használjunk, a ˝(local)˝ vagy ˝localhost˝ nem működik.
(A syntax highlighter egy kicsit belezavarodott a backslash-ekbe. A kód helyes, csak a színezés nem. Sorry.)
update: a fenti szkript akkor fut hibátlanul, ha pkg_list.ps1 néven mentjük el, és abból a könyvtárból futtatjuk, ahová tettük. Ha a $folder mappa alatti almappák tartalma is kell, akkor $drill=1 paraméterrel hívjuk meg. Pl.: .\pkg_list "MSDB" "." 1. Ilyenkor saját magát hívja, pkg_list néven. Már a következő poszton járt az eszem. :)
A GetDtsServerPackageInfos meghívásához a Microsoft.SqlServer.ManagedDTS
assembly-re van szükségünk. Csakhogy ennek a dll-nek az SQL Server 2012 RC0-val már a .NET 4-es verziója érkezik. Mivel
a PowerShell a .NET 2-re van felkészítve, ez gondot jelent. Két
lehetőségünk van:
Ha a gépen fut SQL 2005/2008/2008R2, akkor
előkereshetjük egy korábbi verzióját. Például: C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SQLServer.ManagedDTS.dll
Engedélyezzük a .NET 4-et a
PowerShell környezetünkben egy config fájl segítségével. Erről bővebben pl. itt vagy itt
lehet infót találni.
Az SSIS 2012-es kiadásával azonban egy teljesen új csomag-telepítő metódus (deploy mode) érkezik, ami átveszi a helyét a korábbi megoldásoknak. A kompatibilitás miatt ugyan továbbra is választható a korábbi módszer, és ugyanezért megmaradtak az msdb.dbo.sysssis... táblák is, de az új módszerhez egy teljesen új struktúra tartozik.
A következő poszt erről fog szólni. Maradjanak velünk, a szünet után folytatjuk! ;)