Creating Stored Procedure

  • New to SQL Server. Looking for help with the following design problem:

    Query:
    Create a procedure named 'delete_asset_log' that takes 1 input listed below:
    @assetlog_id INT
    Based on this input, the procedure must do the following operation:

    Design Rules:

    1) If id(i.e, assetlog_id) passed as input matches with id in asset_log table, then if expected_checkin_date of that id is less than today's date and status is 'Returned', then delete the log with id equal to assetlog_id passed as input.
    2) If id(i.e, assetlog_id) passed as input does not match with id in asset_log table, then insert an error_msg of type varchar(200) i.e, 'Asset log id does not exist' into asset_error_log table.

    My Attempt: 
    I'm getting a 'Runtime Error' when I attempt to execute the following:

    CREATE PROCEDURE delete_asset_log
      @assetlog_id INT
    AS
    BEGIN
    IF EXISTS (SELECT * FROM asset_log
         WHERE id = @assetlog_id AND expected_checkedin_date < GETDATE( ) AND status = 'Returned')
           DELETE FROM asset_log
    IF NOT EXISTS (SELECT * FROM asset_log
         WHERE id = @assetlog_id)
          INSERT INTO asset_error_log (error_msg)
           VALUES ( 'Asset log id does not exist')
    END

  • If I understand your requirements correctly, this should do the job: Notice that I added the where condition to the delete
    CREATE PROCEDURE delete_asset_log 
    @assetlog_id INT
    AS
    BEGIN
    IF EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id AND expected_checkedin_date < GETDATE( ) AND status = 'Returned')
    BEGIN
        DELETE FROM asset_log WHERE id = @assetlog_id
    END
    ELSE -- (No need to specify this) IF NOT EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id)
    BEGIN
          INSERT INTO asset_error_log (error_msg) 
          VALUES ( 'Asset log id does not exist') 
    END

    END

  • Worked great! Thanks a ton!

  • dreynolds 13587 - Wednesday, October 11, 2017 9:40 AM

    If I understand your requirements correctly, this should do the job: Notice that I added the where condition to the delete
    CREATE PROCEDURE delete_asset_log 
    @assetlog_id INT
    AS
    BEGIN
    IF EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id AND expected_checkedin_date < GETDATE( ) AND status = 'Returned')
    BEGIN
        DELETE FROM asset_log WHERE id = @assetlog_id
    END
    ELSE -- (No need to specify this) IF NOT EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id)
    BEGIN
          INSERT INTO asset_error_log (error_msg) 
          VALUES ( 'Asset log id does not exist') 
    END

    END

    Worked great! Thanks!

  • dreynolds 13587 - Wednesday, October 11, 2017 9:40 AM

    If I understand your requirements correctly, this should do the job: Notice that I added the where condition to the delete
    CREATE PROCEDURE delete_asset_log 
    @assetlog_id INT
    AS
    BEGIN
    IF EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id AND expected_checkedin_date < GETDATE( ) AND status = 'Returned')
    BEGIN
        DELETE FROM asset_log WHERE id = @assetlog_id
    END
    ELSE -- (No need to specify this) IF NOT EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id)
    BEGIN
          INSERT INTO asset_error_log (error_msg) 
          VALUES ( 'Asset log id does not exist') 
    END

    END

    Have one more I'm struggling with if you don't mind taking a look. I need to use TRY...CATCH BLOCK for this one.

    Query:
    Create a procedure named 'insert_category' that takes 2 inputs listed below:
    @category_id INT and @category_name VARCHAR 
    Based on this input, the procedure must do the following operation:

    Design Rules:
    1) If id (i.e, category_id) passed as input is UNIQUE, then insert category_id and category_name as a new record into category table.
    2) If the category_id passed as input is NOT UNIQUE, then catch the exception and insert an error_msg of type varchar(200) i.e, 'Category id is not Unique' into category_error_log table.

    My Attempt:
    I'm getting a 'Runtime Error' when I attempt to execute the following:

    CREATE PROCEDURE insert_category
      @category_id INT, @category_name VARCHAR(200)
    AS
    BEGIN TRY
    IF NOT EXISTS (SELECT * FROM category
         WHERE id = @category_id
         AND name = @category_name )
    INSERT INTO category (id, name)  
    VALUES (@category_id , @category_name)
    END TRY
    BEGIN CATCH
      INSERT INTO category_error_log (error_msg)
      VALUES ( 'Category id is not Unique')
    END CATCH

  • the only thing I can see is that you do not have the BEGIN/END block for the creation of the procedure: Compare my code below to yours.

    CREATE PROCEDURE insert_category
    @category_id INT, @category_name VARCHAR(200)
    AS
    BEGIN  -- <-- you are missing this

        BEGIN TRY
            IF NOT EXISTS (SELECT * FROM category
                             WHERE id = @category_id
                             AND name = @category_name )
            BEGIN
                INSERT INTO category (id, name)
                VALUES (@category_id , @category_name)
            END

        END TRY
        BEGIN CATCH
         INSERT INTO category_error_log (error_msg)
         VALUES ( 'Category id is not Unique')
        END CATCH

    END -- <-- you are missing this

  • Some best practice that I use and should help you understand your code better are as follows:

    1) Be sure to indent your code blocks
    2) I use verbose BEGIN/END blocks within branches of code, (this helps someone else read what I am trying to do)
    3) Format your queries in a consistent pattern that a reader (or you) can easily understand what is being attempted

    Hope that helps

  • dreynolds 13587 - Wednesday, October 11, 2017 10:29 AM

    the only thing I can see is that you do not have the BEGIN/END block for the creation of the procedure: Compare my code below to yours.

    CREATE PROCEDURE insert_category
    @category_id INT, @category_name VARCHAR(200)
    AS
    BEGIN  -- <-- you are missing this

        BEGIN TRY
            IF NOT EXISTS (SELECT * FROM category
                             WHERE id = @category_id
                             AND name = @category_name )
            BEGIN
                INSERT INTO category (id, name)
                VALUES (@category_id , @category_name)
            END

        END TRY
        BEGIN CATCH
         INSERT INTO category_error_log (error_msg)
         VALUES ( 'Category id is not Unique')
        END CATCH

    END -- <-- you are missing this

    BEGIN/END is not required in the definition of a stored proc.

    I think that the poster is receiving a runtime error. It would be helpful to see the full text of this error message.

    The absence of evidence is not evidence of absence
    - Martin Rees
    The absence of consumable DDL, sample data and desired results is, however, evidence of the absence of my response
    - Phil Parkin

  • Also, I noticed that your requirement was only to check if the category_id was unique.
    In your query, you are checking if category_id and category_name together are unique. (Not sure if that will cause you a problem)

  • dreynolds 13587 - Wednesday, October 11, 2017 10:38 AM

    Also, I noticed that your requirement was only to check if the category_id was unique.
    In your query, you are checking if category_id and category_name together are unique. (Not sure if that will cause you a problem)

    That was it. Needed to remove @category_name from the SELECT statement. Thanks again.

  • dreynolds 13587 - Wednesday, October 11, 2017 9:40 AM

    If I understand your requirements correctly, this should do the job: Notice that I added the where condition to the delete
    CREATE PROCEDURE delete_asset_log 
    @assetlog_id INT
    AS
    BEGIN
    IF EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id AND expected_checkedin_date < GETDATE( ) AND status = 'Returned')
    BEGIN
        DELETE FROM asset_log WHERE id = @assetlog_id
    END
    ELSE -- (No need to specify this) IF NOT EXISTS (SELECT * FROM asset_log WHERE id = @assetlog_id)
    BEGIN
          INSERT INTO asset_error_log (error_msg) 
          VALUES ( 'Asset log id does not exist') 
    END

    END

    The existence check is one hit on the table and the DELETE is a second.  Just a performance and resource usage tip... I believe you can do it in a single hit with something like the following.


     CREATE PROCEDURE delete_asset_log
            @assetlog_id INT
         AS
     DELETE FROM dbo.asset_log
      WHERE id = @assetlog_id
        AND expected_checkedin_date < GETDATE( )
        AND status = 'Returned'
    ;
     INSERT INTO asset_error_log
            (error_msg)
     SELECT 'Asset log id '+CONVERT(VARCHAR(20),@assetlog_id)+'does not exist'
      WHERE @@ROWCOUNT = 0
    ;

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

Viewing 11 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic. Login to reply