31. oktober 2002 - 20:51Der er
25 kommentarer og 1 løsning
SQL server agent.
Hejsa!
Et spørgsmål til de lidt mere hardcore SQL-administratorer, tror jeg:
Hvordan afvikler jeg et job på samtlige databaser i systemet samtidigt!?
Mit problem er flg.:
I en web-applikation holder min SQL-server styr på hvilke sessions der er aktive på mine websites. Der kører et Job hvert 20. minut, der sikrer at alle sessions bliver "nulstillede", hvis der ikke har været aktivitet i 20 minutter. Problemet er bare, at hver gang jeg replikerer en database, så skal jeg rent fysisk gå ind og oprette et nyt job for hver database. Er der ikke mulighed for, at man kan sætte en option til at opdatere samtlige databaser hvert 20. minut med den samme stored procedure?
I lang tid har samarbejdsbranchen fokuseret på at forbedre enhedsfunktioner – bedre kameraer, klarere lyd og smartere software. Men den virkelige forvandling handler ikke om funktioner.
Det er netop et T-SQL job jeg kører. Indtil nu har jeg oprettet et job for hver database, som laver en "Exec sp_MystoredProcedure" på pågældende database.
Så hvad du siger er, at jeg istedet kan lave en Select på sysdatabases i Master-tabellen, og så loope igennem?
Der er en lille bi-ting forbundet ved mit spørgsmål, for det er nemlig ikke *ALLE* databaserne der indeholder den tabel, som jeg skal checke på. Findes der også en mulighed for at checke, om den pågældende tabel eksisterer før man afvikler sin stored procedure? Den skal f.eks ikke køres på "Northwind" eller "Pubs"..
Først: Denne sql returnere samtlige databaser, der indeholder tabellen 'authors'
DECLARE DBCursor CURSOR KEYSET FOR Select name from sysdatabases where sid <> 0x01
DECLARE @name sysname DECLARE @SQL nvarchar(400) DECLARE @Count int OPEN DBCursor
FETCH NEXT FROM DBCursor INTO @name WHILE (@@fetch_status <> -1) BEGIN IF (@@fetch_status <> -2) BEGIN SELECT @Count=object_id(@name + '..authors') IF @Count>0 Begin PRINT @Name End END FETCH NEXT FROM DBCursor INTO @name END
Jeg er ked af det, men det gi'r fuldstændigt samme fejl! :(
DECLARE DBCursor CURSOR KEYSET FOR Select name from sysdatabases where sid <> 0x01
DECLARE @name sysname DECLARE @SQL nvarchar(400) DECLARE @Count int OPEN DBCursor
FETCH NEXT FROM DBCursor INTO @name WHILE (@@fetch_status <> -1) BEGIN IF (@@fetch_status <> -2) BEGIN SELECT @Count=object_id(@name + '..sessions') IF @Count>0 Begin exec sp_executesql N'use ' + @name + N' exec KillSessions' End END FETCH NEXT FROM DBCursor INTO @name END
Nu melder den ikke fejl, men den afvikler heller ikke min KillSessions procedure. Er der nogle muligheder for at lave noget fejlsøgning, evt. udskrive nogle variabler eller noget, når man afvikler jobbet, så man kan se hvorfor den ikke fungerer?
Okay.. Nu looper den igennem og @@fetch_status er lig med 0 hele vejen igennem.. Men det virker stadig ikke helt. Men hvis jeg indsætter følgende linie:
print @name
i det følgende
IF (@@fetch_status <> -2) BEGIN SELECT @Count=object_id(@name + 'SESSIONS') IF @Count>0 print @name /* Hvis jeg indsætter denne linie, så virker det */ Begin set @SQL=N'use ' + @name + N' exec KillSessions' exec sp_executesql @SQL End END
ja, så virker det??
Men det holder jo ikke, når det skal op og ligge på web-serveren!
Så er det fordi Begin/End blokken ligger udenfor IF sætningen når du indsætter din linie. Dette betyder, at der ikke laves check på om tabellen eksisterer i databasen.
Nu har jeg ændret det tilbage, så der står ...SESSIONS, og det giver samme resultat: Intet. Den siger bare
The command(s) completed successfully.
Uden, at der er ændret en tøddel.
Hvis jeg sætter print @name ind efter "BEGIN" så sker der ingenting. Hvis jeg derimod sætter det lige før "BEGIN", så virker det perfekt. Den looper igennen, ekekverer proceduren og adskillige rows bliver "affected" fuldstændigt som den skal!?
@count returnerer intet. Den er totalt tom, men funktionen looper igennen og executer KillSessions fuldstændigt som den skal. Fjerner jeg "print @count" virker det ikke længere!
SELECT object_id('pubs..authors') returner ingen ting, men looper igennen som den skal, så længe der står "print @count". Fjerner jeg dette, så looper den heller ikke og returnerer ingen ting!
Jeg tror jeg skal prøve lidt mere SQL-programmering. Det er sgu' lidt anderledes at arbejde i end de sædvanlige sprog jeg bruger, men det er vel bare en vanesag! Spændende er det ihvertfald! Der er mange muligheder!!
Ha' en fornøjelig aften og endnu engang tak for din store indsats! :)
/thomas
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.