12. januar 2006 - 09:53Der er
36 kommentarer og 1 løsning
Trigger hvis temperatur over +5C
Systemet skal kunne sende en mail når temperaturen på en af vores følere kommer over +5C. Databasen opdateres med målerdata hver 30 min., hvilket afvikler triggeren. Jeg har følgende stump af en trigger, men mangler den del der undersøger om værdien er over +5C. Feltet der skal undersøges hedder....hmm....mitFelt. :)
CREATE TRIGGER alerter ON [dbo].[minTabel] AFTER UPDATE, INSERT AS
DECLARE @recipients_var as varchar(255), @subject_var as varchar(255), @Message_var as varchar(255)
SELECT @recipients_var = 'me@mail.dk' SELECT @subject_var = 'Temperatur alert' SELECT @Message_var = 'Temperaturen er over +5C, tag de fornødne forholdsregler'
CREATE TRIGGER alerter ON [dbo].[minTabel] AFTER UPDATE, INSERT AS
DECLARE @recipients_var as varchar(255), @subject_var as varchar(255), @Message_var as varchar(255)
SELECT @recipients_var = 'me@mail.dk' SELECT @subject_var = 'Temperatur alert' SELECT @Message_var = 'Temperaturen er over +5C, tag de fornødne forholdsregler'
if exists (select * from inserted where mitFelt > 5) EXEC master..xp_sendmail @recipients = @recipients_var, @subject = @subject_var, @message = @Message_var
Når du arbejder med triggere, har du to tabeller: Inserted og Deleted.
Deleted indeholder de slettede poster og er aktuel i Delete triggere og Update triggere. I Update triggere er det posternes nye værdier, i Delete triggere de slettede poster.
Inserted indeholder de nye poster og er aktuel i Insert og Update triggere. I Insert triggere er det de nye poster, og i Update triggere er det posternes nye værdier.
Jeg er dog ikke helt sikker på at det bliver som jeg gerne vil have det. I systemet er der 50 målere, som alle bliver opdateret ca. samtidig (en post indeholder et ID (Identity-felt), Måler, Dato, Klokkeslæt og Tæller) Når der bliver indsat en ny post, skal der checkes for de 10 udvalgte målere. Er det nødvendigt med 10 triggers med hver deres navn eller kan man lave det som en stor trigger? De trigges ikke ved samme værdi...
Målere, som indeholder de enkelte målere MålerAlarmer, som indeholder målernes alarmindstillinger (temperaturoverskridelse osv.) Denne har en fremmednøgle til Målere. Kan også indholde oplysninger om hvem, hvad og hvor omkring modtager.
På den måde kan du i triggerne lave et join mellem Inserted og MålerAlarmer og hente de alarm/målerspecifikke oplysninger.
Nu hedder den jo AFTER UPDATE, INSERT Men hvad hvis jeg kun ville have efter indsættelse af data? Sommetider opdateres data manuelt og hvis noget går galt i opdateringen, skal brugeren helst ikke have 5000-6000 mails/SMS!
Der kommer da også flere og flere krav! Hvis måleren kommer under den specificerede værdi, skal der checkes om den har været tidligere (1 time tilbage, dvs. 3 målinger i alt som skal overskride grænsen) Der skal så sendes en mail indeholdende data for det seneste døgn for den pågældende måler! Jeg har #¤%# ikke point nok til at reward'e sådan et spørgsmål...! :(
Det bliver vist noget langhåret trigger noget, det her! Kender intet til triggere, men må hellere læse lidt på det (har heldigvis adgang til www.books24x7.com)
Med den sidste betingelse, så bliver den langhåret ja.
Spørgsmålet er, om det ville være nemmere at droppe triggerne med dette udseende og i stedet lave en trigger, som sætter et flag - f.eks. i en dummy-tabel.
Derefter kunne der laves et program, som hvert minut tjekker på dette flag. Når flaget bliver sat, undersøger programmet det sidste døgns målinger og handler ud fra det med mail/sms osv. Når behandlingen er færdig, nulstilles flaget.
Du skulle vel ikke ligge inde med et eksempel? Fra BOL:
DATEPART and SET DATEFIRST (Level 4) SQL Server 6.x SQL Server 2000 The SET DATEFIRST setting of the DATEPART function had no effect on the week datepart. The week datepart may give values different from earlier versions of Microsoft® SQL Server™. However, any difference will appear only if the SET DATEFIRST setting is not the default (the U.S. English default is 7). If the year provided in the DATEPART function has 366 days, a week value of 54 can be returned if the first week of the year starts on a Saturday, and the year ends on the same day of the week with the first day of the week counted from Sunday.
When using the ISO 8601 standard, week values are always from 1 through 53, as the first week of the year is guaranteed to have a minimum of 4 days.
Expect different results as compared to earlier versions of SQL Server. Use the default value for SET DATEFIRST so that DATEPART returns the expected results for the week datepart. Otherwise, DATEPART values will be one less than expected
Kan jeg få "overført" værdien af den indsatte post til mailen/SMS'en? (følgende virker ikke, jeg får en fejl: Error 116: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS)
IF Exists (SELECT * FROM inserted WHERE Måler='MinMåler' AND Tæller > -15) SELECT @Value_var = (SELECT * FROM inserted WHERE Måler='MinMåler' AND Tæller > -15)
Problemet er, at forsøger at lægge et resultatsæt i en variabel. Du er nødt til at definere en variabel for hver information, du vil have med i mailen og så kombinere disse variable i mailen efterfølgende:
if exists (select * from inserted where Måler='MinMåler' and Tæller > -15) select @Value_Var1=Value1, @Value_Var2=Value2 from inserted where Måler = 'MinMåler' and Tæller > -15
Herefter bruger du @Value_Var1, @Value_Var2 osv. som du har lyst til.
Det behøver jeg heller ikke, Triggeren henter alt fra feltet Mail, som jo ikke behøver indeholde kun en mailadresse (feltet er af typen varchar(255), så ingen problemer i at angive flere adresser)
Jeg kan da også blive ved! Er det muligt at formattere felterne Dato og Klokkeslæt (som ligger i inserted), så jeg for Dato kun får datoen og for Klokkeslæt kun...ja, klokkeslættet? Jeg troede man kunne bruge Format((SELECT Klokkeslæt FROM inserted WHERE Måler=MinMåler' AND Tæller > + @LimitValue_var)) Men den går ikke.
Glemte at sige at Dato og Klokkeslæt variablerne er defineret som varchar(255). Prøvede at lade dem være som datetime og smalldatetime, men så går det galt med variablen Klokkeslæt: ODBC: Kaldet lykkedes ikke. [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting datetime from character string. (#241)
Hvad jeg ikke forstår er, at du vil have delt dato og klokkeslæt ud i to variable? Oplysningen ligger fint i en datetime. Og den kan du konvertere/formattere til tekst ved hjælp af Convert (se BOL).
Det vil jeg heller ikke. Eksempel på dato i den sammenkædede tabel: 18-01-2006
Eksempel på tidspunkt: 01-01-1900 09:36:19
Men når jeg henter dem ind i triggervariablerne (som varchar, datetime eller smalldatetime), vil dato få påhæftet et tidspunkt (mener det var 12:00 AM) og tidspunktet ændres der ikke på. Derfor vil jeg have skåret noget af dem begge.
convert(nvarchar, Dato, 105) og convert(nvarchar, Klokkeslæt, 108)
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.