{"id":73080,"date":"2017-01-30T14:41:10","date_gmt":"2017-01-30T14:41:10","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/uncategorized\/oracle-for-absolute-beginners-other-sql-functions\/"},"modified":"2021-07-14T13:06:57","modified_gmt":"2021-07-14T13:06:57","slug":"oracle-for-absolute-beginners-other-sql-functions","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/oracle-for-absolute-beginners-other-sql-functions\/","title":{"rendered":"Oracle for Absolute Beginners: Other SQL Functions"},"content":{"rendered":"<p>Here\u2019s a simple trick you can play on your friends. Ask them to pick a number from 1 to 10, and tell them you\u2019ll read their mind and magically extract from it the number they\u2019ve chosen. Don\u2019t give them too long to choose; then put on your best imitation of a magician and say\u2026<\/p>\n<p><strong>7.<\/strong><\/p>\n<p>I don\u2019t know why, but it\u2019s always 7. Ask people to pick a random number less than 10, and they almost always say 7. I can\u2019t explain it, but feel free to use it to freak your friends out.<\/p>\n<p>Now, here\u2019s how you can freak your Oracle developer friends out. Tell them you can guess the functions they use the most in their code: it\u2019ll be one of the following: count, to_char, to_date, round or nvl.<\/p>\n<p>OK, so maybe that\u2019s not as mind-bending a trick, but the point I\u2019m trying to make is that even though SQL comes equipped with well over a hundred standard functions we all fall back on the same small set that we\u2019re used to, sometimes making them jump through impossible hoops just because we\u2019re not aware of a less popular function designed specifically to meet that need.<\/p>\n<p>I\u2019ve had my nose deep in <a href=\"http:\/\/docs.oracle.com\/cd\/B19306_01\/server.102\/b14200\/functions001.htm\" target=\"_blank\">the documentation<\/a>, and here are 7\u00a0functions of whose existence I\u2019d like to remind you.<\/p>\n<h5>NVL2<\/h5>\n<p>Ah, <code>NVL2<\/code> &#8211; like the Hollywood sequel that is inevitably less awesome than the original movie, or the geeky younger sibling of the most popular kid in school, <code>NVL2<\/code> has never had the currency that the ubiquitous <code>NVL<\/code> has. But don\u2019t dismiss it out of hand.<\/p>\n<p>Whereas <code>NVL<\/code> allows you determine the value to be returned if your parameterised expression is null and returns the value of that expression if it is not null, <code>NVL2<\/code> also gives you control of exactly what happens when the expression is not null.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/oracle\/2017\/01\/nvl2.gif\" alt=\"NVL2\" \/><\/p>\n<p class=\"caption\">NVL2 Syntax (source: <a href=\"http:\/\/docs.oracle.com\/database\/121\/SQLRF\/functions132.htm#SQLRF00685\" target=\"_blank\">docs.oracle.com<\/a>)<\/p>\n<p><code>NVL2<\/code> evaluates\u00a0<em>expr1<\/em> and returns\u00a0<em>expr2<\/em> if it is NOT null, but returns\u00a0<em>expr3<\/em> if it is.<\/p>\n<p>It is the equivalent of the following DECODE statement:<\/p>\n<pre>DECODE(expr1, NULL, expr2, expr3)<\/pre>\n<p>And if you&#8217;re wondering when you might use this, here&#8217;s an example using the EMP table.<\/p>\n<p>Some employees earn a commission on top of their salaries, while others have to make do with just their salary. If we wanted to produce a report on employees&#8217; total pay (i.e, salary plus commission, if commission is not null) we might say:<\/p>\n<pre>SELECT empno,\u00a0NVL2(comm,sal+comm,sal) \"Total Pay\"\r\nFROM emp;<\/pre>\n<h5>NULLIF<\/h5>\n<p><code>NULLIF<\/code> has a different trick up its sleeve. What it does is compare two values that it is fed and if they are equal it returns a null, otherwise it returns the first parameter.\u00a0<\/p>\n<p><img decoding=\"async\" title=\"\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/oracle\/2017\/01\/nullif.gif\" alt=\"NULLIF\" \/> <\/p>\n<p class=\"caption\">NULLIF Syntax (source: <a href=\"http:\/\/docs.oracle.com\/database\/121\/SQLRF\/functions128.htm#SQLRF00681\" target=\"_blank\">docs.oracle.com<\/a>)<\/p>\n<p>Basically, what I&#8217;m saying is that if\u00a0<em>expr1<\/em> and\u00a0<em>expr2<\/em> are equal, <code>NULLIF<\/code> will return a null, and if they&#8217;re not it&#8217;ll return\u00a0<em>expr1.<\/em> That is the equivalent of the following case statement.<\/p>\n<pre>CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END<\/pre>\n<p>And if you&#8217;re trying to think up a situation where this might be useful, here&#8217;s one. Imagine that in addition to your paid staff your company also retains a number of unpaid interns. The EMP table has a salary of 0 against their names, but you&#8217;d rather output a null when you query the table.<\/p>\n<pre>SELECT empno, NULLIF(sal,0) \"Salary\"\r\nFROM emp;<\/pre>\n<h5>COALESCE<\/h5>\n<p>Erm, yes, we&#8217;re still talking about nulls, about &#8216;nothing&#8217;. Who&#8217;d have thought we could spend all this time together chatting about nothing. (Yes, I know that technically, nulls aren&#8217;t &#8216;nothing&#8217;, they&#8217;re &#8216;undefined&#8217;. But I don&#8217;t know any jokes about &#8216;undefined&#8217;, so leave me alone.)<\/p>\n<p>Back to <code>coalesce<\/code>. The <code>coalesce<\/code> function accepts 2 or more parameters and will return the first one that is not null.\u00a0<\/p>\n<p>What that means is that:<\/p>\n<pre>COALESCE(expr1, expr2, expr3)<\/pre>\n<p>will return\u00a0<em>expr1<\/em> if is not null, but will return\u00a0<em>expr2<\/em> if it is and\u00a0<em>expr2<\/em> is not. However, if both\u00a0<em>expr1<\/em> and\u00a0<em>expr2<\/em> are null, it will return\u00a0<em>expr3<\/em> if it is not undefined. And so on. This is the equivalent of the following case statement:<\/p>\n<pre>CASE\r\n\u00a0 \u00a0WHEN expr1 IS NOT NULL THEN expr1\r\n\u00a0 \u00a0WHEN expr2 IS NOT NULL THEN expr2\r\n\u00a0 \u00a0ELSE expr3\r\nEND<\/pre>\n<p>In other words, <code>coalesce<\/code> can accomplish in one line something that, with a case statement, has the potential to get as long-winded and boring as listening to your ex talk about how perfect their new lover is.<\/p>\n<h5>LNNVL<\/h5>\n<p>Before we move on from nulls, I&#8217;ve got one more: <code>LNNVL<\/code>.<\/p>\n<p>It&#8217;s a bit of an odd one; it&#8217;s like that game Opposites, that young children enjoy playing. It accepts an expression as a parameter and, if that expression evaluates as\u00a0<em>true<\/em>, it&#8217;ll return\u00a0<em>false;<\/em> if, however, the expression evaluates as\u00a0<em>false<\/em> or unknown, it&#8217;ll return\u00a0<em>true.<\/em>\u00a0<\/p>\n<p>As <code>LNNVL<\/code> returns a Boolean, it can only be used in where clauses or in the when conditions of a case statement.\u00a0<\/p>\n<p>However, more than\u00a0<em>how<\/em> you&#8217;re probably wondering\u00a0<em>why &#8211; <\/em>and<em> when &#8211;\u00a0<\/em> you&#8217;d ever want to use <code>LNNVL<\/code>. Here&#8217;s an example. Remember that company you&#8217;re running that has both paid staff and unpaid volunteers? Say you wanted to query the\u00a0<em>sal<\/em>\u00a0column of the\u00a0<em>Emp<\/em>\u00a0table to find all members of the team who earn less than \u00a310,000. The following query will return all\u00a0<em>paid<\/em> staff who earn less than that amount:<\/p>\n<pre>SELECT empno\r\nFROM emp\r\nWHERE sal &lt;10000;<\/pre>\n<p>But one way to include unpaid volunteers in the resultset (beyond the obvious solution of wrapping an NVL around the\u00a0<em>sal<\/em>\u00a0in the where clause) is to use <code>LNNVL<\/code> as follows:<\/p>\n<pre>SELECT emp_id\r\nFROM employees\r\nWHERE LNNVL(salary &gt;= 10000);<\/pre>\n<p>This works because <code>LNNVL<\/code> returns\u00a0<em>true<\/em> when the condition it is fed is\u00a0<em>false<\/em> (i.e salary is less than 10000) or unknown (i.e salary is null).\u00a0<\/p>\n<p>Oh, and if you were wondering what on earth <code>LNNVL<\/code> stands for, it is: <em>logical not null value<\/em>. I bet you&#8217;re sorry you asked.<\/p>\n<h5>Compose<\/h5>\n<p>We&#8217;re moving on from functions concerning nulls, so compose yourself.<\/p>\n<p>The <code>compose<\/code> function accepts a string as a parameter &#8211; <code>CHAR<\/code>, <code>VARCHAR2<\/code>, <code>NCHAR<\/code>, <code>NVARCHAR2<\/code>, <code>CLOB<\/code>, or <code>NCLOB -\u00a0<\/code>and translates it into\u00a0a Unicode string in its fully normalized form in the same character set as the input. \u00a0Unicode, as you probably already know, is the standard that allows for consistent representation of text from the various writing systems. What this then means is that if you&#8217;re like me and were brought up with only 26 boring characters in your alphabet, <code>compose<\/code> allows you access all those exotic characters that other peoples use. \u00a0Wanna go to Germany and order a Big Mac &#8211; <em>ein<\/em>\u00a0<i>Big M\u00e4c &#8211;\u00a0<\/i> for a Nigerian named Sola &#8211; <em>S\u1ecdl\u00e1<\/em>? Alright, big spender. \u00a0First you&#8217;ll need to know what the code point is for your particular <a href=\"https:\/\/www.merriam-webster.com\/dictionary\/diaeresis\" target=\"_blank\">diaeresis<\/a>\u00a0and then combine it &#8211; <em>compose<\/em> it &#8211;\u00a0with the right letter. For example, the code point for the double dots &#8211; the umlaut &#8211; is 0308, so if you wanted to order that burger it&#8217;ll be:<\/p>\n<pre>SELECT 'Big M'||COMPOSE ( 'a' || UNISTR('\\0308') )||'c' \r\nFROM DUAL;\u00a0<\/pre>\n<p>And the code point for the dot that goes under letters is 0323, while the accent is 0301 (no, I haven&#8217;t got them all memorised; I&#8217;m using <a href=\"http:\/\/www.unicode.org\/charts\/PDF\/U0300.pdf\" target=\"_blank\">this chart<\/a>). So that Nigerian name is:\u00a0<\/p>\n<pre>SELECT 'S'||COMPOSE ( 'o' || UNISTR('\\0323') )||'l'||COMPOSE ( 'a' || UNISTR('\\0301') ) \r\nFROM DUAL;\u00a0<\/pre>\n<p>Basically, what <code>compose<\/code> does is introduce the ordinary character &#8211; the &#8216;a&#8217;, for instance &#8211; to \u00a0the combining diaeresis &#8211; the<strong> \u0308<\/strong>, for instance &#8211; and encourage them to have a baby together: the\u00a0<i>\u00e4.<\/i><\/p>\n<h5>UNISTR<\/h5>\n<p>Actually, I&#8217;ve done this backwards. \u00a0You might have noticed the call to <code>UNISTR<\/code> in the examples above. \u00a0The <code>UNISTR<\/code> function accepts character data and returns it in the national character set. You can feed it a Unicode encoding value &#8211; in the form of \u00a0&#8216;\\<em>nnnn<\/em>&#8216; where &#8216;nnnn&#8217; is the hexadecimal value of a character in UCS-2 encoding format. \u00a0Here&#8217;s an example of what I mean:\u00a0<\/p>\n<pre>SELECT UNISTR('\\00c6') \"unistr\" \r\nFROM DUAL;\r\n\r\nunistr\r\n------\r\n\u00c6\r\n<\/pre>\n<p>You can combine ASCII strings with Unicode encoding values in your calls to <code>unistr<\/code>. So, returning to the examples we used when talking about compose, you could run the following:<\/p>\n<pre>SELECT UNISTR('Big M\\00e4c') \"unistr\" \r\nFROM DUAL;\r\n\r\nunistr\r\n------\r\nBig M\u00e4c\r\n<\/pre>\n<p>This is because the Unicode encoding value for an a with an umlaut is \\ooe4. Here&#8217;s <a href=\"https:\/\/unicode-table.com\/en\/#control-character\" target=\"_blank\">a list<\/a> if you&#8217;re looking for other characters.\u00a0<\/p>\n<p>In my current job, I help manage a database that sits beneath a public-facing Apex website, and occasionally we are tripped up by non-Latin characters. <code>Unistr<\/code> &#8211; and to a lesser extent, <code>compose<\/code> &#8211; are my secret weapons in those instances.<\/p>\n<h5>DECOMPOSE<\/h5>\n<p>I might as well mention <code>decompose<\/code> too, cos it hangs out with <code>compose<\/code> and <code>unistr<\/code>, not because I find myself using it much.\u00a0<\/p>\n<p><code>Decompose<\/code>, unsurprisingly, is the opposite of <code>compose<\/code>. \u00a0You know how <code>compose<\/code> will take, for instance, an a and the umlaut code point and &#8211; <em>abracadabra<\/em> &#8211; return an a-umlaut. \u00a0Well, <code>decompose<\/code> will take an a-umlaut, or any such character, and return an a followed by the two dots of an umlaut.\u00a0<\/p>\n<p><img decoding=\"async\" title=\"\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/oracle\/2017\/01\/allthingsoracle_decompose.jpg\" \/><\/p>\n<h5>Conclusion<\/h5>\n<p>These 7 functions won&#8217;t change your life. Sorry about that. But what they might do is help get you out of a bind, or help save you a few lines of convoluted code. \u00a0And that&#8217;s not nothing.<\/p>\n<p>Now, close your eyes and think of a number from 1 to 10.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here\u2019s a simple trick you can play on your friends. Ask them to pick a number from 1 to 10, and tell them you\u2019ll read their mind and magically extract from it the number they\u2019ve chosen. Don\u2019t give them too long to choose; then put on your best imitation of a magician and say\u2026 7. I don\u2019t know why, but&hellip;<\/p>\n","protected":false},"author":221907,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143533],"tags":[48379,48380,48398,48437,48450,48451,124952,48531],"coauthors":[48557],"class_list":["post-73080","post","type-post","status-publish","format-standard","hentry","category-oracle-databases","tag-coalesce","tag-compose","tag-decompose","tag-lnnvl","tag-nullif","tag-nvl2","tag-redgate-deploy","tag-unistr"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73080","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221907"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=73080"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73080\/revisions"}],"predecessor-version":[{"id":88953,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73080\/revisions\/88953"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=73080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=73080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=73080"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=73080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}