{"id":20,"date":"2012-02-23T22:00:40","date_gmt":"2012-02-23T22:00:40","guid":{"rendered":"http:\/\/en.latindevelopers.com\/ivancp\/?p=20"},"modified":"2012-02-24T03:58:17","modified_gmt":"2012-02-24T03:58:17","slug":"simulating-sequences-in-mysql","status":"publish","type":"post","link":"http:\/\/en.latindevelopers.com\/ivancp\/2012\/simulating-sequences-in-mysql\/","title":{"rendered":"Creating sequences in MySQL"},"content":{"rendered":"<p><img loading=\"lazy\" class=\"alignright size-full wp-image-21\" title=\"MySQL Logo\" src=\"http:\/\/en.latindevelopers.com\/ivancp\/wp-content\/uploads\/2012\/02\/logo-mysql-170x115.png\" alt=\"\" width=\"170\" height=\"115\" \/>Those who have used PostgresSQL usually gets lazy when write the SQL code to auto-numeric fields, but we miss that feature when we are in a MySQL database.<\/p>\n<p>As we know, MySQL have auto-increment fields, that are very useful too, but we miss that feature when we are in a PostgreSQL database.<\/p>\n<p>I will try to explain how to simulate sequences like PostgreSQL in MySQL. But in what situations we would need sequences in MySQL? some ideas:<\/p>\n<ul>\n<li>When we need more than one auto-numeric field in the same table.<\/li>\n<li>When we need a global counter to use in more than one table, procedures, etc.<\/li>\n<li>I can&#8217;t think more situations, but I&#8217;m sure at some point we can found one.<\/li>\n<\/ul>\n<p><strong>OK let&#8217;s start:<\/strong><\/p>\n<p>We need to create a table to store the current sequence value (if this table is created inside\u00a0mysql database\u00a0 is not bad idea)<\/p>\n<pre lang=\"mysql\">create table _sequence\r\n(\r\n\tseq_name varchar(50) not null primary key,\r\n\tseq_val int unsigned not null\r\n);<\/pre>\n<p>Now we need a function to get the next sequence value, including these cases:<\/p>\n<ul>\n<ul>\n<li>Create a sequence name if the sequence name don&#8217;t exists (is not necessary get complicated).<\/li>\n<li>Increase the sequence number each function call.<\/li>\n<\/ul>\n<\/ul>\n<p>There is the function\u00a0 <code>getNextSeq<\/code> it receive sequence name as parameter:<\/p>\n<pre lang=\"mysql\">delimiter \/\/\r\ndrop function if exists getNextSeq\/\/\r\n\r\ncreate function getNextSeq(sSeqName varchar(50)) returns int unsigned\r\nbegin\r\n    declare nLast_val int;\r\n\r\n    set nLast_val =  (select seq_val\r\n                          from _sequence\r\n                          where seq_name = sSeqName);\r\n    if nLast_val is null then\r\n        set nLast_val = 1;\r\n        insert into _sequence (seq_name,seq_val)\r\n        values (sSeqName,nLast_Val);\r\n    else\r\n        set nLast_val = nLast_val + 1;\r\n        update _sequence set seq_val = nLast_val\r\n        where seq_name = sSeqName;\r\n    end if;\r\n\r\n    return nLast_val;\r\nend\/\/\r\n\r\ndelimiter ;<\/pre>\n<p>&nbsp;<\/p>\n<p>The next step is to create\u00a0 (to maintain purposes) a stored procedure to modify the current sequence value:<\/p>\n<pre lang=\"mysql\">drop procedure if exists sp_setSeqVal\/\/\r\n\r\ncreate procedure sp_setSeqVal(sSeqName varchar(50), nVal int unsigned)\r\nbegin\r\n    if (select count(*) from _sequence where seq_name = sSeqName) = 0 then\r\n        insert into _sequence (seq_name,seq_val)\r\n        values (sSeqName,nVal);\r\n    else\r\n        update _sequence set seq_val = nVal\r\n        where seq_name = sSeqName;\r\n    end if;\r\nend\/\/\r\n\r\ndelimiter ;<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>That&#8217;s it!<\/strong>, just one more thing: testing. Creating a table with two auto-numeric fields using simulated sequences:<\/p>\n<pre lang=\"mysql\">create table multiple_autonums\r\n(\r\n   id int not null primary key auto_increment,\r\n   seq_1 int, -- sequence 1\r\n   seq_2 int, -- sequence 2\r\n   unique(seq_1),\r\n   unique(seq_2)\r\n);<\/pre>\n<p>We must create a before-insert trigger on table:<\/p>\n<pre lang=\"mysql\">delimiter \/\/\r\ndrop trigger if exists multiple_autonums_ai\/\/\r\n\r\ncreate trigger multiple_autonums_bi before insert on multiple_autonums\r\nfor each row\r\nbegin\r\n   set new.seq_1 = getNextSeq(\"seq_1\");\r\n   set new.seq_2 = getNextSeq(\"seq_2\");\r\nend\/\/\r\n\r\ndelimiter ;<\/pre>\n<p>&nbsp;<\/p>\n<p>Run some tests:<\/p>\n<pre lang=\"mysql\">-- inserting new values.\r\ninsert into multiple_autonums (id) values (null),(null),(null);\r\n\r\n-- getting the inserted values\r\nselect * from multiple_autonums;\r\n+----+-------+-------+\r\n| id | seq_1 | seq_2 |\r\n+----+-------+-------+\r\n|  1 |     1 |     1 |\r\n|  2 |     2 |     2 |\r\n|  3 |     3 |     3 |\r\n+----+-------+-------+\r\n3 rows in set (0.00 sec)\r\n\r\n-- Changing sequence current values\r\n\r\ncall sp_setSeqVal(\"seq_1\",47);\r\ncall sp_setSeqVal(\"seq_2\",9786);\r\n\r\n-- Inserting new values\r\ninsert into multiple_autonums (id) values (null),(null),(null);\r\n\r\n-- Seeing what happen.\r\nselect * from multiple_autonums;\r\n+----+-------+-------+\r\n| id | seq_1 | seq_2 |\r\n+----+-------+-------+\r\n|  1 |     1 |     1 |\r\n|  2 |     2 |     2 |\r\n|  3 |     3 |     3 |\r\n|  4 |    48 |  9787 |\r\n|  5 |    49 |  9788 |\r\n|  6 |    50 |  9789 |\r\n+----+-------+-------+<\/pre>\n<p>&nbsp;<\/p>\n<p>What do you think?<\/p>\n<p>This simulated sequence don&#8217;t consider some stuffs but it works and can be helpful. Even you can modify the function to make more complex generation of next value.<\/p>\n<div id=\"gt-res-content\">\n<div dir=\"ltr\">Hope you find it useful.<\/div>\n<\/div>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-official sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-twitter\"><a href=\"https:\/\/twitter.com\/share\" class=\"twitter-share-button\" data-url=\"http:\/\/en.latindevelopers.com\/ivancp\/2012\/simulating-sequences-in-mysql\/\" data-text=\"Creating sequences in MySQL\"  >Tweet<\/a><\/li><li class=\"share-facebook\"><div class=\"fb-share-button\" data-href=\"http:\/\/en.latindevelopers.com\/ivancp\/2012\/simulating-sequences-in-mysql\/\" data-layout=\"button_count\"><\/div><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Those who have used PostgresSQL usually gets lazy when write the SQL code to auto-numeric fields, but we miss that feature when we are in a MySQL database. As we know, MySQL have auto-increment fields, that are very useful too, but we miss that feature when we are in a PostgreSQL database. I will try [&hellip;]<\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-official sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-twitter\"><a href=\"https:\/\/twitter.com\/share\" class=\"twitter-share-button\" data-url=\"http:\/\/en.latindevelopers.com\/ivancp\/2012\/simulating-sequences-in-mysql\/\" data-text=\"Creating sequences in MySQL\"  >Tweet<\/a><\/li><li class=\"share-facebook\"><div class=\"fb-share-button\" data-href=\"http:\/\/en.latindevelopers.com\/ivancp\/2012\/simulating-sequences-in-mysql\/\" data-layout=\"button_count\"><\/div><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"author":1,"featured_media":21,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[4],"tags":[5],"jetpack_featured_media_url":"http:\/\/en.latindevelopers.com\/ivancp\/wp-content\/uploads\/2012\/02\/logo-mysql-170x115.png","jetpack_shortlink":"https:\/\/wp.me\/p2f09V-k","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/posts\/20"}],"collection":[{"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/comments?post=20"}],"version-history":[{"count":4,"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/posts\/20\/revisions"}],"predecessor-version":[{"id":24,"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/posts\/20\/revisions\/24"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/media\/21"}],"wp:attachment":[{"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/media?parent=20"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/categories?post=20"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/en.latindevelopers.com\/ivancp\/wp-json\/wp\/v2\/tags?post=20"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}