{"id":73174,"date":"2015-02-25T11:00:16","date_gmt":"2015-02-25T11:00:16","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/uncategorized\/data-masking-using-sql-loader\/"},"modified":"2021-07-14T13:07:27","modified_gmt":"2021-07-14T13:07:27","slug":"data-masking-using-sql-loader","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/data-masking-using-sql-loader\/","title":{"rendered":"Data Masking using SQL Loader"},"content":{"rendered":"<p>I use\u00a0Enterprise Manager Cloud Control to mask Oracle databases so they can\u00a0be shared with our ERP vendor. I intended to do the same with our legacy Informix database but I found that we did not have the Database Gateway licenses required for using Enterprise Manager Data Masking Pack on Informix. We also had a requirement to replace customer names and addresses with a set of twenty arbitrary values. Due to referential integrity, the replacement values had to be deterministic\/repeatable &#8211; not random.<\/p>\n<p>The Informix DBA sent me flat file exports from the Informix tables containing the customer records. I mounted these as external tables and wrote SQL to select from them and write to Oracle tables. This was so slow that I abandoned that idea and decided to load the files into Oracle tables using SQL Loader. It&#8217;s been so long since I have used SQL Loader that I had to relearn how to build control files. I was amazed at how fast the data loaded. I had the idea of using\u00a0SQL Loader to mask the data during the load.<\/p>\n<p>I decided to use the oracle_hash function inside a case statement in the SQL Loader control file specification for the sensitive columns. This let me replace the names and addresses with new values in a repeatable way. I forced the names to uppercase and then produced a hash value which I associated with the fictional name. That fictional name got loaded into the Oracle table.<\/p>\n<p>I am very satisfied with the results and happy I had the opportunity to re-familiarize myself with SQL Loader.<\/p>\n<p>Here&#8217;s the content of the control file:<\/p>\n<blockquote>\n<p>options<br \/>\n(<br \/>\ndirect=true, rows=200000, multithreading=true<br \/>\n)<br \/>\nunrecoverable<br \/>\nload data<br \/>\ninfile customers.unl badfile customers.bad discardfile customers.dis<br \/>\ninto table customers<br \/>\nfields terminated by &#8216;|&#8217;<br \/>\n(<br \/>\ncust_num,<br \/>\nfirst_name &#8220;case<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 0) then &#8216;Andy&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 1) then &#8216;Brenda&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 2) then &#8216;Jim&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 3) then &#8216;Cathy&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 4) then &#8216;Bob&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 5) then &#8216;Sue&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 6) then &#8216;Joe&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 7) then &#8216;Carmen&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 8) then &#8216;Jose&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 9) then &#8216;Claire&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 10) then &#8216;Ron&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 11) then &#8216;Misty&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 12) then &#8216;Jason&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 13) then &#8216;Glenda&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 14) then &#8216;Rick&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 15) then &#8216;Suzy&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 16) then &#8216;Peter&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 17) then &#8216;Sara&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 18) then &#8216;Isaac&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 19) then &#8216;Helen&#8217;<br \/>\nwhen (ora_hash(upper(:first_name),20,0) = 20) then &#8216;Nathan&#8217;<br \/>\nelse &#8216;ERROR&#8217; end&#8221;,<br \/>\nlast_name &#8220;case<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 0) then &#8216;Jones&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 1) then &#8216;Hay&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 2) then &#8216;Smith&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 3) then &#8216;Gonzales&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 4) then &#8216;Wu&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 5) then &#8216;Cho&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 6) then &#8216;Einstein&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 7) then &#8216;Ward&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 8) then &#8216;Magee&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 9) then &#8216;Morgan&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 10) then &#8216;Tenkiller&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 11) then &#8216;Rice&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 12) then &#8216;Namath&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 13) then &#8216;DeMarco&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 14) then &#8216;Obama&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 15) then &#8216;Bush&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 16) then &#8216;Grant&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 17) then &#8216;Lee&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 18) then &#8216;Blount&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 19) then &#8216;Bain&#8217;<br \/>\nwhen (ora_hash(upper(:last_name),20,0) = 20) then &#8216;Adams&#8217;<br \/>\nelse &#8216;ERROR&#8217; end&#8221;,<br \/>\naddress1 &#8220;case<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 0) then &#8217;10 Main&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 1) then &#8217;11 1st&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 2) then &#8217;22 2nd&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 3) then &#8217;33 3rd&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 4) then &#8217;44 4th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 5) then &#8217;55 5th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 6) then &#8217;66 6th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 7) then &#8217;77 7th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 8) then &#8217;88 8th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 9) then &#8217;99 9th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 10) then &#8216;100 10th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 11) then &#8216;111 11th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 12) then &#8216;222 22nd&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 13) then &#8216;333 33rd&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 14) then &#8216;444 44th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 15) then &#8216;555 55th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 16) then &#8216;666 66th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 17) then &#8216;777 77th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 18) then &#8216;888 88th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 19) then &#8216;999 99th&#8217;<br \/>\nwhen (ora_hash(upper(:address1),20,0) = 20) then &#8216;2000 20th&#8217;<br \/>\nelse &#8216;ERROR&#8217; end&#8221;,<br \/>\ncity,<br \/>\nstate,<br \/>\nzip,<br \/>\ncountry_code,<br \/>\nphone &#8220;upper(&#8216;8005551212&#8217;)&#8221;,<br \/>\nemail &#8220;upper(&#8216;me\\@mydomain.com&#8217;)&#8221; ,<br \/>\ncreate_date date &#8216;mm\/dd\/yyyy&#8217;,<br \/>\n)<\/p>\n<\/blockquote>\n<p style=\"padding-left: 30px;\">This article has been kindly republished with permission from <a href=\"https:\/\/steveharville.wordpress.com\/2015\/01\/07\/data-masking-using-sql-loader\/\">Steve Harville&#8217;s blog<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I use\u00a0Enterprise Manager Cloud Control to mask Oracle databases so they can\u00a0be shared with our ERP vendor. I intended to do the same with our legacy Informix database but I found that we did not have the Database Gateway licenses required for using Enterprise Manager Data Masking Pack on Informix. We also had a requirement to replace customer names and&hellip;<\/p>\n","protected":false},"author":316185,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143533],"tags":[48387,4459,48508],"coauthors":[],"class_list":["post-73174","post","type-post","status-publish","format-standard","hentry","category-oracle-databases","tag-data-masking","tag-oracle","tag-sql-loader"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73174","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\/316185"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=73174"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73174\/revisions"}],"predecessor-version":[{"id":91664,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73174\/revisions\/91664"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=73174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=73174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=73174"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=73174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}