简体   繁体   中英

Stored procedure : Select data from Table "A" and insert data on Table "B"

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM