{"id":36,"date":"2007-04-04T14:06:01","date_gmt":"2007-04-04T04:06:01","guid":{"rendered":"http:\/\/helms-deep.net\/~rwh\/blog\/?p=36"},"modified":"2007-04-04T14:23:48","modified_gmt":"2007-04-04T04:23:48","slug":"the-pain-of-myob-odbc","status":"publish","type":"post","link":"https:\/\/helms-deep.net\/~rwh\/blog\/?p=36","title":{"rendered":"The pain of MYOB ODBC"},"content":{"rendered":"<p>OK, if you&#8217;re like me, you&#8217;re used to coding on UNIX.  So when, as is pretty much inevitable (unless you&#8217;re living in a university or somewhere unrealistic like that), you have to code on Windows, it can be a bit of a shock.  Which is to be expected&#8230; proprietary binaries everywhere&#8230; argh.<\/p>\n<p>But I wasn&#8217;t expecting it to be quite this painful.  Connecting to MYOB using their ODBC connector is akin to standing on one leg, touching your nose just so, and trying to piss into a specific well in an ice-tray.  Put that one in your freezer and freeze it!  To make matters worse, we want to use PHP for all of this, and MYOB provides examples only in Microsoft&#8217;s favorite languages like C# and *gasp* ASP.  AND, before version 6, you couldn&#8217;t even insert stuff into their database identified by the primary key.  Read that again.  You have to insert it based on last name.  LAST FRIGGIN NAME.  So if you have two Smiths, well&#8230; it assigns it to the first one. Gah.  Anyway, it seems that with MYOB Premier version 10 and ODBC version 6, you can actually do these fundamental things.<\/p>\n<p>So y&#8217;all don&#8217;t have to go through the same pain we did, here is our example code.  One in Perl, the other in PHP.<\/p>\n<p><!--more--><\/p>\n<p>NOTE: WordPress is hopelessly munging my code.  You can download unmunged versions here:  <a href=\"http:\/\/helms-deep.net\/~rwh\/files\/myob_odbc.php.zip\">PHP<\/a>, <a href=\"http:\/\/helms-deep.net\/~rwh\/files\/myob_odbc.pl.zip\">Perl<\/a>.<\/p>\n<p><strong>PHP:<\/strong><\/p>\n<blockquote><p>Connecting to ODBC&lt;br&gt;<br \/>\n&lt;?php<br \/>\n$dsn = &#8216;DSN=MYOB; TYPE=MYOB; ACCESS_TYPE=READ_WRITE; DRIVER_COMPLETION=DRIVER_NOPROMPT; NETWORK_PROTOCOL=NONET; SQL_ATTR_AUTOCOMMIT=0; INSERT_TYPE=UPDATE_DUPLICATES;&#8217;;<\/p>\n<p>$id=odbc_connect($dsn,&#8217;your username&#8217;,&#8217;your password&#8217;);<br \/>\nodbc_autocommit($id, FALSE);<br \/>\n$result=odbc_tables($id);<\/p>\n<p>$tables=array();<br \/>\necho &#8220;listing all tables:&#8221;;<br \/>\nwhile(odbc_fetch_row($result)) {<br \/>\nif(odbc_result($result,&#8221;TABLE_TYPE&#8221;)==&#8221;TABLE&#8221;) {<br \/>\necho &#8220;&lt;br&gt;&#8221;.odbc_result($result,&#8221;TABLE_NAME&#8221;);<br \/>\n}<br \/>\n}<\/p>\n<p>if($id==0) {<br \/>\necho(&#8220;odbc_connect failed&#8221;);<br \/>\n}<br \/>\necho &#8220;&lt;br&gt;doing insert&#8221;;<br \/>\n$query=&#8221;<br \/>\nINSERT\u00c2\u00a0 INTO Import_Items<br \/>\n(ItemNumber, ItemName, Buy, Sell, Inventory, AssetAccount, IncomeAccount, ExpenseAccount)<br \/>\nVALUES\u00c2\u00a0 (&#8216;538&#8217;, &#8216;php&#8217;, &#8216;Y&#8217;, &#8216;Y&#8217;, &#8216;Y&#8217;, &#8216;10000&#8217;, &#8216;40000&#8217;, &#8216;60000&#8217;)&#8221;;<br \/>\n$res=odbc_prepare($id, $query);<br \/>\nodbc_execute($res);<\/p>\n<p>$query=&#8221;END TRANSACTION&#8221;;<br \/>\n$res=odbc_prepare($id, $query);<br \/>\nodbc_execute($res);<\/p>\n<p>odbc_commit($id);<\/p>\n<p>if(odbc_error())<br \/>\n{<br \/>\necho odbc_errormsg($id);<br \/>\n}<br \/>\n?&gt;<br \/>\n&lt;br&gt;done.<\/p><\/blockquote>\n<p><strong>Perl:<\/strong><\/p>\n<blockquote><p>use DBI;<br \/>\nuse strict;<br \/>\nuse Shell;<\/p>\n<p>my $mysql_query;<br \/>\nmy $dsn = &#8216;DSN=MYOB; TYPE=MYOB; ACCESS_TYPE=READ_WRITE; DRIVER_COMPLETION=DRIVER_NOPROMPT; NETWORK_PROTOCOL=NONET; SQL_ATTR_AUTOCOMMIT=0; INSERT_TYPE=UPDATE_DUPLICATES;IDENTIFY_BY=RECORD_ID&#8217;;<br \/>\nmy $dbh = DBI-&gt;connect(&#8220;dbi:ODBC:$dsn&#8221;,&#8217;your username&#8217;,&#8217;your password&#8217;,<br \/>\n{RaiseError=&gt;1,AutoCommit=&gt;0})<br \/>\nor die &#8220;Couldn&#8217;t connect to database: &#8220;. DBI-&gt;errstr;<br \/>\nmy @row;<\/p>\n<p>my $query;<\/p>\n<p>sub err_handler<br \/>\n{<br \/>\nmy ($sql_state, $msg, $nativeerr) = @_;<\/p>\n<p>print &#8220;===&gt; sql_state: $sql_state\\n===&gt; msg: $msg\\n===&gt; nativeerr: $nativeerr\\n&#8221;;<br \/>\nreturn 1;<br \/>\n}<\/p>\n<p>$dbh-&gt;{odbc_err_handler} = \\&amp;err_handler;<br \/>\n$dbh-&gt;{odbc_exec_direct} = 1;<\/p>\n<p>$query=&#8221;INSERT INTO Import_Customer_Cards (CoLastName, FirstName, CardID)<br \/>\nVALUES ((&#8216;ffff&#8217;, &#8216;ffff&#8217; , &#8216;555555&#8217;), (&#8216;VAN BERT&#8217;, &#8216;RUSSELL&#8217; , &#8216;12345&#8217;))&#8221;;<\/p>\n<p>my $sth = $dbh-&gt;prepare($query)<br \/>\nor die &#8220;Unable to prepare query\\n&#8221;;<br \/>\n$sth-&gt;execute<br \/>\nor die &#8220;Unable to execute query\\n&#8221;;<\/p>\n<p>my $query=&#8221;END TRANSACTION&#8221;;<\/p>\n<p>my $sth = $dbh-&gt;prepare($query)<br \/>\nor die &#8220;Unable to prepare query\\n&#8221;;<br \/>\n$sth-&gt;execute<br \/>\nor die &#8220;Unable to execute query\\n&#8221;;<\/p>\n<p>$dbh-&gt;commit();<\/p>\n<p>$dbh-&gt;disconnect;<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>OK, if you&#8217;re like me, you&#8217;re used to coding on UNIX. So when, as is pretty much inevitable (unless you&#8217;re living in a university or somewhere unrealistic like that), you have to code on Windows, it can be a bit &hellip; <a href=\"https:\/\/helms-deep.net\/~rwh\/blog\/?p=36\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"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,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-36","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=\/wp\/v2\/posts\/36","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=36"}],"version-history":[{"count":0,"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=\/wp\/v2\/posts\/36\/revisions"}],"wp:attachment":[{"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=36"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=36"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/helms-deep.net\/~rwh\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=36"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}