SQL Trigger to allow only customers who are old enough to buy a book?












0















I have 3 tables, person, audiobook and audiobook_purchases. My database is running MariaDB.





  • person has fields: id, date_of_birth;


  • audiobook has fields: ISBN, age_rating, title;


  • audiobook_purchases has fields: ISBN, customer_id, date_of_purchase;


I'm trying to write a trigger to make sure that when a customer tried to purchases an audiobook, they are old enough to do so according to the age_rating in audiobook.



For example, If Harry Potter and the Philosipher's Stone had age rating 16 and customer Jennifer (ID 1) with date of birth 2010-01-01 tried to purchase this book, this would not be allowed, but Dominick(ID 2) with date_of_birth 1978-01-01 would be allowed.



Please could someone show me a way to run this trigger?










share|improve this question

























  • Question is pretty much unclear on what you are trying to do here. This is generally not the way we add Triggers. Also, n characters should definitely be interfering with the Trigger definition.

    – Madhur Bhaiya
    Nov 24 '18 at 21:01











  • The trigger is to determine whether a customer, who is trying to buy an audiobook, is old enough to purchase this audiobook. Their date of birth is stored in the 'person' table and the age rating for an audiobook is in the 'audiobook' table. I want to prevent insertion of an entry in the 'audiobook_purchases' table if they are not old enough.

    – Ariane Hine
    Nov 24 '18 at 21:03











  • Please edit the question; add table structure details of the concerned tables. Add some sample data. Please read this link: Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Madhur Bhaiya
    Nov 24 '18 at 21:04











  • How do you edit the question?

    – Ariane Hine
    Nov 24 '18 at 21:06











  • Just below the question, you can see a text saying "Edit" (besides "Share"). You can also use this link: stackoverflow.com/posts/53462268/edit

    – Madhur Bhaiya
    Nov 24 '18 at 21:09
















0















I have 3 tables, person, audiobook and audiobook_purchases. My database is running MariaDB.





  • person has fields: id, date_of_birth;


  • audiobook has fields: ISBN, age_rating, title;


  • audiobook_purchases has fields: ISBN, customer_id, date_of_purchase;


I'm trying to write a trigger to make sure that when a customer tried to purchases an audiobook, they are old enough to do so according to the age_rating in audiobook.



For example, If Harry Potter and the Philosipher's Stone had age rating 16 and customer Jennifer (ID 1) with date of birth 2010-01-01 tried to purchase this book, this would not be allowed, but Dominick(ID 2) with date_of_birth 1978-01-01 would be allowed.



Please could someone show me a way to run this trigger?










share|improve this question

























  • Question is pretty much unclear on what you are trying to do here. This is generally not the way we add Triggers. Also, n characters should definitely be interfering with the Trigger definition.

    – Madhur Bhaiya
    Nov 24 '18 at 21:01











  • The trigger is to determine whether a customer, who is trying to buy an audiobook, is old enough to purchase this audiobook. Their date of birth is stored in the 'person' table and the age rating for an audiobook is in the 'audiobook' table. I want to prevent insertion of an entry in the 'audiobook_purchases' table if they are not old enough.

    – Ariane Hine
    Nov 24 '18 at 21:03











  • Please edit the question; add table structure details of the concerned tables. Add some sample data. Please read this link: Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Madhur Bhaiya
    Nov 24 '18 at 21:04











  • How do you edit the question?

    – Ariane Hine
    Nov 24 '18 at 21:06











  • Just below the question, you can see a text saying "Edit" (besides "Share"). You can also use this link: stackoverflow.com/posts/53462268/edit

    – Madhur Bhaiya
    Nov 24 '18 at 21:09














0












0








0








I have 3 tables, person, audiobook and audiobook_purchases. My database is running MariaDB.





  • person has fields: id, date_of_birth;


  • audiobook has fields: ISBN, age_rating, title;


  • audiobook_purchases has fields: ISBN, customer_id, date_of_purchase;


I'm trying to write a trigger to make sure that when a customer tried to purchases an audiobook, they are old enough to do so according to the age_rating in audiobook.



For example, If Harry Potter and the Philosipher's Stone had age rating 16 and customer Jennifer (ID 1) with date of birth 2010-01-01 tried to purchase this book, this would not be allowed, but Dominick(ID 2) with date_of_birth 1978-01-01 would be allowed.



Please could someone show me a way to run this trigger?










share|improve this question
















I have 3 tables, person, audiobook and audiobook_purchases. My database is running MariaDB.





  • person has fields: id, date_of_birth;


  • audiobook has fields: ISBN, age_rating, title;


  • audiobook_purchases has fields: ISBN, customer_id, date_of_purchase;


I'm trying to write a trigger to make sure that when a customer tried to purchases an audiobook, they are old enough to do so according to the age_rating in audiobook.



For example, If Harry Potter and the Philosipher's Stone had age rating 16 and customer Jennifer (ID 1) with date of birth 2010-01-01 tried to purchase this book, this would not be allowed, but Dominick(ID 2) with date_of_birth 1978-01-01 would be allowed.



Please could someone show me a way to run this trigger?







sql triggers mariadb






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 25 '18 at 11:50









Dave

2,59471726




2,59471726










asked Nov 24 '18 at 20:53









Ariane HineAriane Hine

11




11













  • Question is pretty much unclear on what you are trying to do here. This is generally not the way we add Triggers. Also, n characters should definitely be interfering with the Trigger definition.

    – Madhur Bhaiya
    Nov 24 '18 at 21:01











  • The trigger is to determine whether a customer, who is trying to buy an audiobook, is old enough to purchase this audiobook. Their date of birth is stored in the 'person' table and the age rating for an audiobook is in the 'audiobook' table. I want to prevent insertion of an entry in the 'audiobook_purchases' table if they are not old enough.

    – Ariane Hine
    Nov 24 '18 at 21:03











  • Please edit the question; add table structure details of the concerned tables. Add some sample data. Please read this link: Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Madhur Bhaiya
    Nov 24 '18 at 21:04











  • How do you edit the question?

    – Ariane Hine
    Nov 24 '18 at 21:06











  • Just below the question, you can see a text saying "Edit" (besides "Share"). You can also use this link: stackoverflow.com/posts/53462268/edit

    – Madhur Bhaiya
    Nov 24 '18 at 21:09



















  • Question is pretty much unclear on what you are trying to do here. This is generally not the way we add Triggers. Also, n characters should definitely be interfering with the Trigger definition.

    – Madhur Bhaiya
    Nov 24 '18 at 21:01











  • The trigger is to determine whether a customer, who is trying to buy an audiobook, is old enough to purchase this audiobook. Their date of birth is stored in the 'person' table and the age rating for an audiobook is in the 'audiobook' table. I want to prevent insertion of an entry in the 'audiobook_purchases' table if they are not old enough.

    – Ariane Hine
    Nov 24 '18 at 21:03











  • Please edit the question; add table structure details of the concerned tables. Add some sample data. Please read this link: Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Madhur Bhaiya
    Nov 24 '18 at 21:04











  • How do you edit the question?

    – Ariane Hine
    Nov 24 '18 at 21:06











  • Just below the question, you can see a text saying "Edit" (besides "Share"). You can also use this link: stackoverflow.com/posts/53462268/edit

    – Madhur Bhaiya
    Nov 24 '18 at 21:09

















Question is pretty much unclear on what you are trying to do here. This is generally not the way we add Triggers. Also, n characters should definitely be interfering with the Trigger definition.

– Madhur Bhaiya
Nov 24 '18 at 21:01





Question is pretty much unclear on what you are trying to do here. This is generally not the way we add Triggers. Also, n characters should definitely be interfering with the Trigger definition.

– Madhur Bhaiya
Nov 24 '18 at 21:01













The trigger is to determine whether a customer, who is trying to buy an audiobook, is old enough to purchase this audiobook. Their date of birth is stored in the 'person' table and the age rating for an audiobook is in the 'audiobook' table. I want to prevent insertion of an entry in the 'audiobook_purchases' table if they are not old enough.

– Ariane Hine
Nov 24 '18 at 21:03





The trigger is to determine whether a customer, who is trying to buy an audiobook, is old enough to purchase this audiobook. Their date of birth is stored in the 'person' table and the age rating for an audiobook is in the 'audiobook' table. I want to prevent insertion of an entry in the 'audiobook_purchases' table if they are not old enough.

– Ariane Hine
Nov 24 '18 at 21:03













Please edit the question; add table structure details of the concerned tables. Add some sample data. Please read this link: Why should I provide an MCVE for what seems to me to be a very simple SQL query?

– Madhur Bhaiya
Nov 24 '18 at 21:04





Please edit the question; add table structure details of the concerned tables. Add some sample data. Please read this link: Why should I provide an MCVE for what seems to me to be a very simple SQL query?

– Madhur Bhaiya
Nov 24 '18 at 21:04













How do you edit the question?

– Ariane Hine
Nov 24 '18 at 21:06





How do you edit the question?

– Ariane Hine
Nov 24 '18 at 21:06













Just below the question, you can see a text saying "Edit" (besides "Share"). You can also use this link: stackoverflow.com/posts/53462268/edit

– Madhur Bhaiya
Nov 24 '18 at 21:09





Just below the question, you can see a text saying "Edit" (besides "Share"). You can also use this link: stackoverflow.com/posts/53462268/edit

– Madhur Bhaiya
Nov 24 '18 at 21:09












1 Answer
1






active

oldest

votes


















1














I don't know MariaDB in particular, so my answer may need some adjustments.



You want to create an insert trigger on audiobook_purchase so that a new order will be inserted only if the person who wants to place the order is old enough according to audiobook.age_rating.



First you need to figure out a way of extracting the year from person.date_of_birth. Something like the YEAR() scalar function will probably be available. MariaDB may also provide a NOW() function, which gives the current date. So the person age right now will be: YEAR(NOW()) - YEAR(person.date_of_birth).



Then you have to write the insert trigger. The tricky part is to query the person table to get the person date_of_birth from his id, then to compare it to audiobook.age_rating.



Let's set out an example. First we declare the tables schemas:



CREATE TABLE person(id, name, date_of_birth);
CREATE TABLE audiobook(isbn, age_rating, title);
CREATE TABLE audiobook_purchases(isbn, customer_id, date_of_purchase);


Then we put in some data:



INSERT INTO person VALUES (10, "jennifer", '2010-01-01');
INSERT INTO person VALUES (20, "dominick", '1978-01-01');
INSERT INTO audiobook VALUES (1234, 16, "harry potter");


Then we create the trigger:



CREATE TRIGGER check_purchases
AFTER INSERT ON audiobook_purchases
FOR EACH ROW
WHEN (
SELECT strftime('%Y', 'now') - strftime('%Y', date_of_birth) AS age
FROM person
WHERE new.customer_id=person.id) < (
SELECT audiobook.age_rating
FROM audiobook
WHERE audiobook.isbn=new.isbn)
BEGIN
DELETE FROM audiobook_purchases
WHERE isbn=new.isbn AND
customer_id=new.customer_id AND
date_of_purchase=new.date_of_purchase;
END;


I'll broke down the trigger into smaller steps:





  1. AFTER INSERT ON audiobook_purchases creates a trigger on table audiobook_purchases which will be triggered after the insertion of a new record.


  2. FOR EACH ROW applies the trigger to each new record inserted.

  3. The WHEN clause limits triggering only to those records who satisfy its condition. On the left side of the < sign of the condition there is a query which selects the age of the customer. On the right side there is a query which selects the age rating of the book. Notice the reference to a new table. This table stores the record which triggers the event (see the two examples below). strftime is a scalar function which formats datetime stamps in SQLite. You can read:
    strftime('%Y', 'now') as YEAR(NOW()) and
    strftime('%Y', date_of_birth) as YEAR(date_of_birth).

  4. Finally between BEGIN and END there are instructions that will be executed on triggering. In this case there is a single instruction which removes the record just inserted. MariaDb may provide a ROLLBACK statement, which can be more efficient than the DELETE statement.


So, for example:



INSERT INTO audiobook_purchases VALUES (1234, 10, '2018-11-25');


will activate the trigger, because the customer with id=10 ('jennifer') is 8 years old and the book with isbn=1234 requires the customer to be at least 16 years old, while:



INSERT INTO audiobook_purchases VALUES (1234, 20, '2018-11-25'); 


will not activate the trigger, because this customer is 40 years old.



You must be aware that this solution silently ignore the invalid order. I don't know if this is your desired behaviour.



I tested this trigger on SQLite 3.11.0, so it may not be compatible with your SQL interpreter.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462268%2fsql-trigger-to-allow-only-customers-who-are-old-enough-to-buy-a-book%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    I don't know MariaDB in particular, so my answer may need some adjustments.



    You want to create an insert trigger on audiobook_purchase so that a new order will be inserted only if the person who wants to place the order is old enough according to audiobook.age_rating.



    First you need to figure out a way of extracting the year from person.date_of_birth. Something like the YEAR() scalar function will probably be available. MariaDB may also provide a NOW() function, which gives the current date. So the person age right now will be: YEAR(NOW()) - YEAR(person.date_of_birth).



    Then you have to write the insert trigger. The tricky part is to query the person table to get the person date_of_birth from his id, then to compare it to audiobook.age_rating.



    Let's set out an example. First we declare the tables schemas:



    CREATE TABLE person(id, name, date_of_birth);
    CREATE TABLE audiobook(isbn, age_rating, title);
    CREATE TABLE audiobook_purchases(isbn, customer_id, date_of_purchase);


    Then we put in some data:



    INSERT INTO person VALUES (10, "jennifer", '2010-01-01');
    INSERT INTO person VALUES (20, "dominick", '1978-01-01');
    INSERT INTO audiobook VALUES (1234, 16, "harry potter");


    Then we create the trigger:



    CREATE TRIGGER check_purchases
    AFTER INSERT ON audiobook_purchases
    FOR EACH ROW
    WHEN (
    SELECT strftime('%Y', 'now') - strftime('%Y', date_of_birth) AS age
    FROM person
    WHERE new.customer_id=person.id) < (
    SELECT audiobook.age_rating
    FROM audiobook
    WHERE audiobook.isbn=new.isbn)
    BEGIN
    DELETE FROM audiobook_purchases
    WHERE isbn=new.isbn AND
    customer_id=new.customer_id AND
    date_of_purchase=new.date_of_purchase;
    END;


    I'll broke down the trigger into smaller steps:





    1. AFTER INSERT ON audiobook_purchases creates a trigger on table audiobook_purchases which will be triggered after the insertion of a new record.


    2. FOR EACH ROW applies the trigger to each new record inserted.

    3. The WHEN clause limits triggering only to those records who satisfy its condition. On the left side of the < sign of the condition there is a query which selects the age of the customer. On the right side there is a query which selects the age rating of the book. Notice the reference to a new table. This table stores the record which triggers the event (see the two examples below). strftime is a scalar function which formats datetime stamps in SQLite. You can read:
      strftime('%Y', 'now') as YEAR(NOW()) and
      strftime('%Y', date_of_birth) as YEAR(date_of_birth).

    4. Finally between BEGIN and END there are instructions that will be executed on triggering. In this case there is a single instruction which removes the record just inserted. MariaDb may provide a ROLLBACK statement, which can be more efficient than the DELETE statement.


    So, for example:



    INSERT INTO audiobook_purchases VALUES (1234, 10, '2018-11-25');


    will activate the trigger, because the customer with id=10 ('jennifer') is 8 years old and the book with isbn=1234 requires the customer to be at least 16 years old, while:



    INSERT INTO audiobook_purchases VALUES (1234, 20, '2018-11-25'); 


    will not activate the trigger, because this customer is 40 years old.



    You must be aware that this solution silently ignore the invalid order. I don't know if this is your desired behaviour.



    I tested this trigger on SQLite 3.11.0, so it may not be compatible with your SQL interpreter.






    share|improve this answer




























      1














      I don't know MariaDB in particular, so my answer may need some adjustments.



      You want to create an insert trigger on audiobook_purchase so that a new order will be inserted only if the person who wants to place the order is old enough according to audiobook.age_rating.



      First you need to figure out a way of extracting the year from person.date_of_birth. Something like the YEAR() scalar function will probably be available. MariaDB may also provide a NOW() function, which gives the current date. So the person age right now will be: YEAR(NOW()) - YEAR(person.date_of_birth).



      Then you have to write the insert trigger. The tricky part is to query the person table to get the person date_of_birth from his id, then to compare it to audiobook.age_rating.



      Let's set out an example. First we declare the tables schemas:



      CREATE TABLE person(id, name, date_of_birth);
      CREATE TABLE audiobook(isbn, age_rating, title);
      CREATE TABLE audiobook_purchases(isbn, customer_id, date_of_purchase);


      Then we put in some data:



      INSERT INTO person VALUES (10, "jennifer", '2010-01-01');
      INSERT INTO person VALUES (20, "dominick", '1978-01-01');
      INSERT INTO audiobook VALUES (1234, 16, "harry potter");


      Then we create the trigger:



      CREATE TRIGGER check_purchases
      AFTER INSERT ON audiobook_purchases
      FOR EACH ROW
      WHEN (
      SELECT strftime('%Y', 'now') - strftime('%Y', date_of_birth) AS age
      FROM person
      WHERE new.customer_id=person.id) < (
      SELECT audiobook.age_rating
      FROM audiobook
      WHERE audiobook.isbn=new.isbn)
      BEGIN
      DELETE FROM audiobook_purchases
      WHERE isbn=new.isbn AND
      customer_id=new.customer_id AND
      date_of_purchase=new.date_of_purchase;
      END;


      I'll broke down the trigger into smaller steps:





      1. AFTER INSERT ON audiobook_purchases creates a trigger on table audiobook_purchases which will be triggered after the insertion of a new record.


      2. FOR EACH ROW applies the trigger to each new record inserted.

      3. The WHEN clause limits triggering only to those records who satisfy its condition. On the left side of the < sign of the condition there is a query which selects the age of the customer. On the right side there is a query which selects the age rating of the book. Notice the reference to a new table. This table stores the record which triggers the event (see the two examples below). strftime is a scalar function which formats datetime stamps in SQLite. You can read:
        strftime('%Y', 'now') as YEAR(NOW()) and
        strftime('%Y', date_of_birth) as YEAR(date_of_birth).

      4. Finally between BEGIN and END there are instructions that will be executed on triggering. In this case there is a single instruction which removes the record just inserted. MariaDb may provide a ROLLBACK statement, which can be more efficient than the DELETE statement.


      So, for example:



      INSERT INTO audiobook_purchases VALUES (1234, 10, '2018-11-25');


      will activate the trigger, because the customer with id=10 ('jennifer') is 8 years old and the book with isbn=1234 requires the customer to be at least 16 years old, while:



      INSERT INTO audiobook_purchases VALUES (1234, 20, '2018-11-25'); 


      will not activate the trigger, because this customer is 40 years old.



      You must be aware that this solution silently ignore the invalid order. I don't know if this is your desired behaviour.



      I tested this trigger on SQLite 3.11.0, so it may not be compatible with your SQL interpreter.






      share|improve this answer


























        1












        1








        1







        I don't know MariaDB in particular, so my answer may need some adjustments.



        You want to create an insert trigger on audiobook_purchase so that a new order will be inserted only if the person who wants to place the order is old enough according to audiobook.age_rating.



        First you need to figure out a way of extracting the year from person.date_of_birth. Something like the YEAR() scalar function will probably be available. MariaDB may also provide a NOW() function, which gives the current date. So the person age right now will be: YEAR(NOW()) - YEAR(person.date_of_birth).



        Then you have to write the insert trigger. The tricky part is to query the person table to get the person date_of_birth from his id, then to compare it to audiobook.age_rating.



        Let's set out an example. First we declare the tables schemas:



        CREATE TABLE person(id, name, date_of_birth);
        CREATE TABLE audiobook(isbn, age_rating, title);
        CREATE TABLE audiobook_purchases(isbn, customer_id, date_of_purchase);


        Then we put in some data:



        INSERT INTO person VALUES (10, "jennifer", '2010-01-01');
        INSERT INTO person VALUES (20, "dominick", '1978-01-01');
        INSERT INTO audiobook VALUES (1234, 16, "harry potter");


        Then we create the trigger:



        CREATE TRIGGER check_purchases
        AFTER INSERT ON audiobook_purchases
        FOR EACH ROW
        WHEN (
        SELECT strftime('%Y', 'now') - strftime('%Y', date_of_birth) AS age
        FROM person
        WHERE new.customer_id=person.id) < (
        SELECT audiobook.age_rating
        FROM audiobook
        WHERE audiobook.isbn=new.isbn)
        BEGIN
        DELETE FROM audiobook_purchases
        WHERE isbn=new.isbn AND
        customer_id=new.customer_id AND
        date_of_purchase=new.date_of_purchase;
        END;


        I'll broke down the trigger into smaller steps:





        1. AFTER INSERT ON audiobook_purchases creates a trigger on table audiobook_purchases which will be triggered after the insertion of a new record.


        2. FOR EACH ROW applies the trigger to each new record inserted.

        3. The WHEN clause limits triggering only to those records who satisfy its condition. On the left side of the < sign of the condition there is a query which selects the age of the customer. On the right side there is a query which selects the age rating of the book. Notice the reference to a new table. This table stores the record which triggers the event (see the two examples below). strftime is a scalar function which formats datetime stamps in SQLite. You can read:
          strftime('%Y', 'now') as YEAR(NOW()) and
          strftime('%Y', date_of_birth) as YEAR(date_of_birth).

        4. Finally between BEGIN and END there are instructions that will be executed on triggering. In this case there is a single instruction which removes the record just inserted. MariaDb may provide a ROLLBACK statement, which can be more efficient than the DELETE statement.


        So, for example:



        INSERT INTO audiobook_purchases VALUES (1234, 10, '2018-11-25');


        will activate the trigger, because the customer with id=10 ('jennifer') is 8 years old and the book with isbn=1234 requires the customer to be at least 16 years old, while:



        INSERT INTO audiobook_purchases VALUES (1234, 20, '2018-11-25'); 


        will not activate the trigger, because this customer is 40 years old.



        You must be aware that this solution silently ignore the invalid order. I don't know if this is your desired behaviour.



        I tested this trigger on SQLite 3.11.0, so it may not be compatible with your SQL interpreter.






        share|improve this answer













        I don't know MariaDB in particular, so my answer may need some adjustments.



        You want to create an insert trigger on audiobook_purchase so that a new order will be inserted only if the person who wants to place the order is old enough according to audiobook.age_rating.



        First you need to figure out a way of extracting the year from person.date_of_birth. Something like the YEAR() scalar function will probably be available. MariaDB may also provide a NOW() function, which gives the current date. So the person age right now will be: YEAR(NOW()) - YEAR(person.date_of_birth).



        Then you have to write the insert trigger. The tricky part is to query the person table to get the person date_of_birth from his id, then to compare it to audiobook.age_rating.



        Let's set out an example. First we declare the tables schemas:



        CREATE TABLE person(id, name, date_of_birth);
        CREATE TABLE audiobook(isbn, age_rating, title);
        CREATE TABLE audiobook_purchases(isbn, customer_id, date_of_purchase);


        Then we put in some data:



        INSERT INTO person VALUES (10, "jennifer", '2010-01-01');
        INSERT INTO person VALUES (20, "dominick", '1978-01-01');
        INSERT INTO audiobook VALUES (1234, 16, "harry potter");


        Then we create the trigger:



        CREATE TRIGGER check_purchases
        AFTER INSERT ON audiobook_purchases
        FOR EACH ROW
        WHEN (
        SELECT strftime('%Y', 'now') - strftime('%Y', date_of_birth) AS age
        FROM person
        WHERE new.customer_id=person.id) < (
        SELECT audiobook.age_rating
        FROM audiobook
        WHERE audiobook.isbn=new.isbn)
        BEGIN
        DELETE FROM audiobook_purchases
        WHERE isbn=new.isbn AND
        customer_id=new.customer_id AND
        date_of_purchase=new.date_of_purchase;
        END;


        I'll broke down the trigger into smaller steps:





        1. AFTER INSERT ON audiobook_purchases creates a trigger on table audiobook_purchases which will be triggered after the insertion of a new record.


        2. FOR EACH ROW applies the trigger to each new record inserted.

        3. The WHEN clause limits triggering only to those records who satisfy its condition. On the left side of the < sign of the condition there is a query which selects the age of the customer. On the right side there is a query which selects the age rating of the book. Notice the reference to a new table. This table stores the record which triggers the event (see the two examples below). strftime is a scalar function which formats datetime stamps in SQLite. You can read:
          strftime('%Y', 'now') as YEAR(NOW()) and
          strftime('%Y', date_of_birth) as YEAR(date_of_birth).

        4. Finally between BEGIN and END there are instructions that will be executed on triggering. In this case there is a single instruction which removes the record just inserted. MariaDb may provide a ROLLBACK statement, which can be more efficient than the DELETE statement.


        So, for example:



        INSERT INTO audiobook_purchases VALUES (1234, 10, '2018-11-25');


        will activate the trigger, because the customer with id=10 ('jennifer') is 8 years old and the book with isbn=1234 requires the customer to be at least 16 years old, while:



        INSERT INTO audiobook_purchases VALUES (1234, 20, '2018-11-25'); 


        will not activate the trigger, because this customer is 40 years old.



        You must be aware that this solution silently ignore the invalid order. I don't know if this is your desired behaviour.



        I tested this trigger on SQLite 3.11.0, so it may not be compatible with your SQL interpreter.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 25 '18 at 16:31









        A. SematA. Semat

        234




        234
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462268%2fsql-trigger-to-allow-only-customers-who-are-old-enough-to-buy-a-book%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Ottavio Pratesi

            Tricia Helfer

            15 giugno