I haven't touched stored procedures and functions for a very long time. So I decided to make a mini-training database for myself.
At the moment, I'm trying to create a procedure that comes in and selects data from one table (Test_trigger) and says that if the sum for a colour exceeds a threshold, then I write an alert row to another table (Test_alm_trigger)
Here are my 2 tables creation script:
create table Test_trigger (
id INT IDENTITY(1,1) PRIMARY KEY,
Couleur VARCHAR(50),
Horodate DATETIME,
Nombre DECIMAL(6,2),
Seuil_fixe INT
);
create table Test_alm_trigger (
id_alm INT IDENTITY(1,1) PRIMARY KEY,
Label VARCHAR(100),
Horodate DATETIME,
Seuil DECIMAL(6,2)
);
To be more precise, the goal is:
when a colour ([Couleur]), such as "Blue", has a sum of the [Nombre] column above the threshold entered ([Seuil_fixe]), then the procedure runs and inserts a row in the Test_alm_trigger table with a [Label], the date the addition was made ( SYSDATETIME() ) and the sum of the [Nombre] column.
I have created this procedure but I am not sure how it works or if it is good or not
CREATE PROCEDURE ajoutL_triggerAlm
(
@Couleur nvarchar(50),
@Label nvarchar(200) = 'Dépassement de seuil',
@Seuil float(4),
@Seuil_fixe float(4),
@Msg nvarchar(200)
)
AS
BEGIN
IF EXISTS (
SELECT [Couleur]
FROM Test_trigger
GROUP BY [Couleur], [Nombre], [Seuil_fixe]
HAVING [Couleur] = @Couleur AND
SUM([Nombre]) = @Seuil AND
[Seuil_fixe] = @Seuil_fixe AND
@Seuil > @Seuil_fixe
)
BEGIN
SET @Msg = 'Debug'
END
ELSE
BEGIN
INSERT INTO Test_alm_trigger
VALUES (@Label, SYSDATETIME(), @Seuil)
END
END
If you have any answers, tips... I'll take them.
Thank you in advance
The main change I would suggest is making your procedure set-based rather than procedural. Relational databases are optimised for set-based operations so you should try and get into the mindset of operating that way yourself.
I've added other best practices.
CREATE PROCEDURE ajoutL_triggerAlm
(
@Couleur nvarchar(50)
, @Label nvarchar(200) = 'Dépassement de seuil'
-- Almost never use float, its not a precise numeric amount and should only be used when specifically required
, @Seuil decimal(8,4)
-- Almost never use float, its not a precise numeric amount and should only be used when specifically required
, @Seuil_fixe decimal(8,4)
, @Msg nvarchar(200)
)
AS
BEGIN
-- Best practice (I'll leave the meaning as an exercise)
-- SQL Server recommendation is to ";" terminate all statements
SET NOCOUNT, XACT_ABORT ON;
-- Best practice, always list the columns you are inserting into
-- Use set-based operations instead of procedural where you can
INSERT INTO dbo.Test_alm_trigger (Label, Horodate, Seuil)
SELECT @Label, SYSDATETIME(), @Seuil
-- Question states when SUM([Nombre] above the threshold @Seuil_fixe - so I think this is the logic
-- Although its not clear where the column Seuil_fixe comes into it
WHERE (
SELECT SUM([Nombre])
FROM Test_trigger
WHERE [Couleur] = @Couleur
) > @Seuil_fixe;
-- Detect failure using @@ROWCOUNT
SET @Msg = CASE WHEN @@ROWCOUNT = 0 THEN 'Debug' ELSE NULL END;
-- Return a status, can use other values to indicate errors
RETURN 0;
END;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.