<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>My Zen Arcade &#187; programming</title>
	<atom:link href="http://myzenarcade.com/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://myzenarcade.com</link>
	<description>How many quarters must be spent to truly know Kung-Fu, Grasshopper?</description>
	<lastBuildDate>Sun, 18 Sep 2011 11:41:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Oracle Tool: Populate Excel Sheets With Table Data</title>
		<link>http://myzenarcade.com/2009/02/24/oracle-tool-populate-excel-sheets-with-table-data/</link>
		<comments>http://myzenarcade.com/2009/02/24/oracle-tool-populate-excel-sheets-with-table-data/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 14:56:23 +0000</pubDate>
		<dc:creator>moleboy</dc:creator>
				<category><![CDATA[Science and Technology]]></category>
		<category><![CDATA[my life]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[vba]]></category>

		<guid isPermaLink="false">http://myzenarcade.com/?p=692</guid>
		<description><![CDATA[And another tool I use a lot.
I often get asked to export all the (relatively small) tables in a schema into worksheets in an excel workbook, one per tab.
Usually, theres a back and forth first with me trying to explain how this probably won&#8217;t mean much, the user
not understanding, me explaining, the user either not [...]]]></description>
			<content:encoded><![CDATA[<!-- sphereit start --><p>And another tool I use a lot.<br />
I often get asked to export all the (relatively small) tables in a schema into worksheets in an excel workbook, one per tab.<br />
Usually, theres a back and forth first with me trying to explain how this probably won&#8217;t mean much, the user<br />
not understanding, me explaining, the user either not caring or still not understanding.<br />
Regardless, I end up having to export the data as they ask.<br />
This isn&#8217;t a big deal especially using Toad.  Unless there&#8217;s 100 tables (or, really, 15 is plenty to make it annoying).<br />
This VBA does that all for you.<br />
As before, you&#8217;ll have to build a form to bring in the relevant options (like schema, db, password).<br />
I also have it set to do its work based on a naming patterns.<br />
For example, maybe I only want tables that start with EST.  If you do or don&#8217;t want that, the relevant line is:<br />
&#8220;Select table_name from dba_tables where owner = &#8216;&#8221; &#038; inSchema &#038; &#8220;&#8216; and table_name like &#8216;&#8221; &#038; inNameString &#038; &#8220;&#8216; order by table_name&#8221;<br />
There is one limitation in that it simply can&#8217;t handle any table with a LOB column (regardless as to the data contained within)</p>
<p>Again, I promise nothing as far as HOW this is written, just the functionality.</p>
<blockquote><p>
Dim strConnect As String<br />
&#8216; Dim RS As Object<br />
    Dim conn As Object<br />
    Dim MyErrors As String<br />
    Dim MyGoodCount As Integer<br />
    Dim MyBadCount As Integer</p>
<p>Private Sub ConnectToOracle(inUID As String, inPWD As String, inServer As String)<br />
&#8216; open the connection to Oracle<br />
    strConnect = &#8220;Driver={Microsoft ODBC for Oracle};&#8221; &#038; &#8220;Server=&#8221; &#038; inServer &#038; &#8220;;uid=&#8221; &#038; inUID &#038; &#8220;;pwd=&#8221; &#038; inPWD &#038; &#8220;;&#8221;<br />
    Set conn = CreateObject(&#8221;ADODB.Connection&#8221;)<br />
    conn.ConnectionString = strConnect<br />
    conn.Open<br />
End Sub</p>
<p>Private Sub getMyRows(inSchema As String, InTable As String)<br />
    Dim RS As Object<br />
    Dim TableSQL As String<br />
    Dim DataType As String<br />
    Dim DataLength As String<br />
    Dim DataPrecision As String<br />
    Dim DataScale As String<br />
    Dim ColCount As Integer<br />
    Dim WS As Worksheet<br />
&#8216; create a sheet with the current table as name<br />
    Worksheets.Add().Name = InTable<br />
    Set RS = CreateObject(&#8221;ADODB.recordset&#8221;)<br />
On Error GoTo GetOut<br />
    TableSQL = &#8220;Select * from &#8221; &#038; inSchema &#038; &#8220;.&#8221; &#038; InTable<br />
&#8216; grab the data<br />
    RS.Open TableSQL, conn, adOpenStatic<br />
    For ColCount = 0 To RS.Fields.Count &#8211; 1<br />
&#8216; set column headings to match table<br />
       ActiveSheet.Cells(1, ColCount + 1).Value = RS.Fields(ColCount).Name<br />
    Next</p>
<p>&#8216; copy table data to sheet<br />
     With Worksheets(InTable).Range(&#8221;A2&#8243;)<br />
On Error GoTo GetOut<br />
        .CopyFromRecordset RS<br />
    End With<br />
    RS.Close</p>
<p>&#8216; a little formatting<br />
    ActiveSheet.Range(&#8221;A1&#8243;).Select<br />
    Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select<br />
    Selection.Columns.AutoFit<br />
    ActiveSheet.Rows(&#8221;1:1&#8243;).Select<br />
    Selection.Font.Bold = True</p>
<p>&#8216; track how many successes<br />
    MyGoodCount = MyGoodCount + 1<br />
    Exit Sub<br />
GetOut:<br />
&#8216; track errors and continue<br />
    MyErrors = MyErrors &#038; &#8220;,&#8221; &#038; InTable<br />
    MyBadCount = MyBadCount + 1<br />
End Sub<br />
Private Sub NewGetMyRows(inSchema As String, InTable As String)<br />
    Dim RST As Object<br />
    Dim TableSQL As String<br />
    Dim DataType As String<br />
    Dim DataLength As String<br />
    Dim DataPrecision As String<br />
    Dim DataScale As String<br />
    Dim ColCount As Integer<br />
    Dim WS As Worksheet</p>
<p>&#8216; this might be useful if we run into very long fields, HOWEVER, that&#8217;ll usually be clobs and those won&#8217;t work anyhow<br />
    Worksheets.Add().Name = InTable<br />
    Set RST = CreateObject(&#8221;ADODB.recordset&#8221;)<br />
    TableSQL = &#8220;Select * from &#8221; &#038; inSchema &#038; &#8220;.&#8221; &#038; InTable<br />
&#8216;    On Error GoTo GetOut<br />
    RST.Open TableSQL, conn<br />
i = 1<br />
For Each fld In RST.Fields<br />
    Worksheets(InTable).Cells(2, i).Value = fld.Name<br />
    i = i + 1<br />
Next fld</p>
<p>Dim j As Long, k As Long</p>
<p>With Worksheets(InTable)<br />
    For j = 1 To RST.RecordCount<br />
        For k = 1 To RST.Fields.Count<br />
            If IsNull(RST(k &#8211; 1)) Then<br />
                .Cells(j + 2, k) = Empty<br />
            Else<br />
                If Len(RST(k &#8211; 1)) > 255 Then<br />
                    For i = 0 To Int(Len(RST(k &#8211; 1)) / 255)<br />
                        .Cells(j + 2, k).Value = .Cells(j + 2, k).Value &#038; Mid(RST(k &#8211; 1), (i * 255) + 1, 255)<br />
                    Next i<br />
                Else<br />
                    .Cells(j + 2, k).Value = RST(k &#8211; 1)<br />
                End If<br />
            End If<br />
        Next k<br />
        RST.MoveNext<br />
    Next j<br />
End With<br />
RST.Close<br />
Exit Sub<br />
GetOut:<br />
MsgBox InTable<br />
&#8216; RST.Close<br />
End Sub</p>
<p>Sub getTables(inUser As String, inPW As String, inDB As String, inSchema As String, inNameString As String)<br />
   Dim RSTables As Object<br />
   Dim TableListSQL As String<br />
   Dim SchemaName As String<br />
   Dim errtext As String<br />
   MyGoodCount = 0<br />
   MyBadCount = 0<br />
   Set RSTables = CreateObject(&#8221;ADODB.recordset&#8221;)<br />
   ConnectToOracle inUser, inPW, inDB<br />
&#8216; grab list of tables and call getMyRows for each table<br />
   TableListSQL = &#8220;Select table_name from dba_tables where owner = &#8216;&#8221; &#038; inSchema &#038; &#8220;&#8216; and table_name like &#8216;&#8221; &#038; inNameString &#038; &#8220;&#8216; order by table_name&#8221;<br />
   RSTables.Open TableListSQL, conn, adOpenStatic<br />
   Do While Not RSTables.EOF<br />
      getMyRows inSchema, (RSTables(&#8221;table_name&#8221;))<br />
      RSTables.MoveNext<br />
   Loop<br />
   RSTables.Close<br />
&#8216; set hint if there were errors<br />
   If MyBadCount > 0 Then<br />
      errtext = &#8220;(Errors may be caused by CLOB/LOB columns)&#8221;<br />
   Else<br />
      errtext = &#8220;&#8221;<br />
   End If<br />
&#8216; report results<br />
   MsgBox &#8220;Completed!  Good:&#8221; &#038; MyGoodCount &#038; &#8221; Bad:&#8221; &#038; MyBadCount &#038; &#8221; &#8221; &#038; errtext &#038; &#8221; Bad Tables:&#8221; &#038; MyErrors</p>
<p>End Sub
</p></blockquote>
<!-- sphereit end --><span style="margin-bottom:40px; border-bottom:none;"><a class="iconsphere" title="Sphere: Related Content" onclick="return Sphere.Widget.search('http://myzenarcade.com/2009/02/24/oracle-tool-populate-excel-sheets-with-table-data/')" href="http://www.sphere.com/search?q=sphereit:http://myzenarcade.com/2009/02/24/oracle-tool-populate-excel-sheets-with-table-data/">Sphere: Related Content</a></span><br/><br/>]]></content:encoded>
			<wfw:commentRss>http://myzenarcade.com/2009/02/24/oracle-tool-populate-excel-sheets-with-table-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle Tool: Excel writes your sqlloader control file</title>
		<link>http://myzenarcade.com/2009/02/24/oracle-tool-excel-writes-your-sqlloader-control-file/</link>
		<comments>http://myzenarcade.com/2009/02/24/oracle-tool-excel-writes-your-sqlloader-control-file/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 14:54:51 +0000</pubDate>
		<dc:creator>moleboy</dc:creator>
				<category><![CDATA[Science and Technology]]></category>
		<category><![CDATA[my life]]></category>
		<category><![CDATA[control file]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[racle]]></category>
		<category><![CDATA[sqlloader]]></category>
		<category><![CDATA[vba]]></category>

		<guid isPermaLink="false">http://myzenarcade.com/?p=689</guid>
		<description><![CDATA[Just a little geek moment here.
For my job, I do a lot of dataloads.  Its actually kind of annoying because ctl files are kind of annoying.
ANYHOO, I got tired of writing the things and the typos and such, so I made a little VBA app in Excel.
The code assumes that the column names are [...]]]></description>
			<content:encoded><![CDATA[<!-- sphereit start --><p>Just a little geek moment here.<br />
For my job, I do a lot of dataloads.  Its actually kind of annoying because ctl files are kind of annoying.<br />
ANYHOO, I got tired of writing the things and the typos and such, so I made a little VBA app in Excel.<br />
The code assumes that the column names are in the first row and are correct.<br />
Basically, it grabs a column name, goes and gets information on the column from the database, and then uses that to make an entry in the control file.<br />
Then it exports the data file.<br />
Note that all I promise from this is that it works for me and works quickly <i>(translation: its a hack, but a hack that gets it done)</i>.<br />
You&#8217;ll need to create a form to go with this since certain information has to be entered.</p>
<p>The code is broken into two modules DATABASEPROCS and BUILDDATALOAD, since I use the DATABASEPROCS for other things as well.</p>
<blockquote><p>
MODULE DATABASEPROCS<br />
Private Sub ConnectToOracle(inUID As String, inPWD As String, inServer As String)<br />
&#8216; open the connection to Oracle<br />
    strConnect = &#8220;Driver={Microsoft ODBC for Oracle};&#8221; &#038; &#8220;Server=&#8221; &#038; inServer &#038; &#8220;;uid=&#8221; &#038; inUID &#038; &#8220;;pwd=&#8221; &#038; inPWD &#038; &#8220;;&#8221;<br />
    Set conn = CreateObject(&#8221;ADODB.Connection&#8221;)<br />
    conn.ConnectionString = strConnect<br />
    conn.Open<br />
End Sub</p>
<p>Function ColumnType(inColName As String, inTabName As String, inConn As Object)<br />
&#8216; attempt to determin the datatype of the column<br />
    Dim RSType As Object<br />
    Dim TypeSQL As String<br />
    Dim DataType As String<br />
    Dim DataLength As String<br />
    Dim DataPrecision As String<br />
    Dim DataScale As String<br />
    Dim col_type As String</p>
<p>    Set RSType = CreateObject(&#8221;ADODB.recordset&#8221;)<br />
&#8216; you can either hardcode owner or, like above, grab it from the form<br />
    TypeSQL = &#8220;Select distinct data_type,data_length, data_precision,data_scale  from all_tab_cols &#8221; &#038; _<br />
    &#8220;where owner = **WHATEVEROWNER** and upper(table_name) = &#8216;&#8221; &#038; UCase(inTabName) &#038; &#8220;&#8216; and upper(column_name)=&#8217;&#8221; &#038; UCase(inColName) &#038; &#8220;&#8216;&#8221;<br />
    RSType.Open TypeSQL, inConn<br />
    If Not (RSType.BOF And RSType.EOF) Then<br />
&#8216; go to the first record<br />
&#8216; Assumes the first record we find is the one to use.  May not always be<br />
        RSType.MoveFirst<br />
        DataType = RSType(&#8221;data_type&#8221;)<br />
        DataLength = RSType(&#8221;data_length&#8221;)<br />
    &#8216; this bit is required due to funky handling of Strings and NULLs from the DB<br />
        If Not IsNull(RSType(&#8221;data_precision&#8221;)) Then<br />
            DataPrecision = RSType(&#8221;data_precision&#8221;)<br />
        Else<br />
            DataPrecision = &#8220;&#8221;<br />
        End If<br />
        If Not IsNull(RSType(&#8221;data_scale&#8221;)) Then<br />
            DataScale = RSType(&#8221;data_scale&#8221;)<br />
        Else<br />
            DataScale = &#8220;&#8221;<br />
        End If</p>
<p>    &#8216; build the datatype based on type, scale, etc.</p>
<p>        If DataType = &#8220;VARCHAR2&#8243; Then<br />
            col_type = DataType &#038; &#8220;(&#8221; &#038; DataLength &#038; &#8220;)&#8221;<br />
    &#8216; logic to determin exactly what kind of number/integer<br />
        ElseIf (DataType = &#8220;NUMBER&#8221; And DataPrecision = &#8220;&#8221; And DataScale = &#8220;0&#8243;) Then<br />
            col_type = &#8220;INTEGER&#8221;<br />
        ElseIf (DataType = &#8220;NUMBER&#8221; And DataPrecision = &#8220;&#8221; And DataScale = &#8220;&#8221;) Then<br />
            col_type = &#8220;NUMBER&#8221;<br />
        ElseIf (DataType = &#8220;NUMBER&#8221; And DataScale = &#8220;&#8221;) Then<br />
            col_type = &#8220;NUMBER(&#8221; &#038; DataPrecision &#038; &#8220;)&#8221;<br />
        ElseIf (DataType = &#8220;NUMBER&#8221;) Then<br />
            col_type = &#8220;NUMBER(&#8221; &#038; DataPrecision &#038; &#8220;,&#8221; &#038; DataScale &#038; &#8220;)&#8221;<br />
        Else<br />
    &#8216; probably just DATE at this point<br />
            col_type = DataType<br />
        End If<br />
    Else<br />
&#8216; No match.  Default to char<br />
        col_type = &#8220;VARCHAR2(2000)&#8221;<br />
    End If<br />
    ColumnType = col_type<br />
    RSType.Close<br />
End Function</p>
<p>Function CtlType(inColName As String, inTabName As String, inConn As Object)<br />
   Dim ColType As String<br />
   Dim CTLDataType As String</p>
<p>   ColType = ColumnType(inColName, inTabName, inConn)<br />
   If InStr(ColType, &#8220;VARCHAR&#8221;) > 0 Then<br />
      CTLDataType = Replace(ColType, &#8220;VARCHAR2&#8243;, &#8220;CHAR&#8221;)<br />
   ElseIf InStr(ColType, &#8220;INTEGER&#8221;) > 0 Then<br />
      CTLDataType = &#8220;INTEGER EXTERNAL&#8221;<br />
   ElseIf InStr(ColType, &#8220;NUMBER&#8221;) > 0 Then<br />
      CTLDataType = &#8220;DECIMAL EXTERNAL&#8221;<br />
   ElseIf InStr(ColType, &#8220;DATE&#8221;) > 0 Then<br />
      CTLDataType = &#8220;CHAR(2000) &#8220;&#8221;decode(length(substr(:&#8221; &#038; inColName &#038; &#8220;,instr(:&#8221; &#038; inColName &#038; &#8220;,&#8217;/',1,2)+1)),2,to_date(:&#8221; &#038; inColName &#038; &#8220;,&#8217;MM/DD/RR&#8217;),to_date(:&#8221; &#038; inColName &#038; &#8220;,&#8217;MM/DD/YYYY&#8217;))&#8221;"&#8221;<br />
   Else<br />
      CTLDataType = &#8220;CHAR(2000)&#8221;<br />
   End If<br />
   CtlType = CTLDataType<br />
End Function</p>
<p>MODULE BUILDDATALOAD<br />
&#8211;<br />
Dim NewConn As Object</p>
<p>Public Sub CreateLoadFiles(InLoadID As String, inCOID As String, inTable As String)<br />
    Dim colnum As Integer<br />
    Dim ctlline(6) As String<br />
    Dim FileDir As String<br />
    Dim cellval As String<br />
    Dim spacing As String<br />
    Dim chartext As String<br />
    Dim endchar As String<br />
    Dim TABDataType As String<br />
    Dim CTLDataType As String<br />
    Dim LineIndex As Integer<br />
    Dim lArr</p>
<p>    Dim retVal As Variant<br />
    Dim NewConn As Object</p>
<p>    Set NewConn = CreateObject(&#8221;ADODB.Connection&#8221;)<br />
    NewConn = DataBaseProcs.ConnectToOracle inUser, inPW, inDB<br />
    NewConn.Open</p>
<p>    endchar = &#8220;,&#8221;<br />
    ctlchartext = &#8220;char(2000)&#8221;<br />
    spacing = &#8221;      &#8221;<br />
    ctlline(0) = &#8220;Load Data&#8221;<br />
    ctlline(1) = &#8220;INFILE &#8216;&#8221; &#038; InLoadID &#038; &#8220;.dat&#8217;&#8221;<br />
    ctlline(2) = &#8220;APPEND INTO Table load_&#8221; &#038; inTable<br />
    ctlline(3) = &#8220;FIELDS TERMINATED BY &#8216;,&#8217; OPTIONALLY ENCLOSED BY &#8216;&#8221; &#038; Chr(34) &#038; &#8220;&#8216;&#8221;<br />
    ctlline(4) = &#8220;TRAILING NULLCOLS &#8221;<br />
&#8216; continue populating ctlline with whatever your control files should start with.  Mine start with a sequence and constant<br />
    ctlline(5) = &#8220;(id          sequence,&#8221;<br />
    ctlline(6) = &#8220;load_id      CONSTANT &#8216;&#8221; &#038; InLoadID &#038; &#8220;&#8216;,&#8221;</p>
<p>    colnum = 1<br />
&#8216; the control file<br />
    FileDir = &#8220;C:\Dataloads\&#8221; &#038; InLoadID &#038; &#8220;\&#8221;<br />
    MkDir (FileDir)<br />
    Open FileDir &#038; InLoadID &#038; &#8220;.ctl&#8221; For Append As #1<br />
&#8216; lines every control file starts with<br />
&#8216; modified based on your ctllines above<br />
    For LineIndex = 0 To 6<br />
        Print #1, ctlline(LineIndex)<br />
    Next LineIndex<br />
&#8216; start at 1,1 and go across the top row until null</p>
<p>    Do Until IsEmpty(ActiveSheet.Cells(1, colnum).Value)<br />
&#8216; if next field is null, then this is the last field and end of file.  Different line-end character<br />
       cellval = Replace(Replace(ActiveSheet.Cells(1, colnum).Text, &#8221; &#8220;, &#8220;&#8221;), &#8220;-&#8221;, &#8220;&#8221;)<br />
       If IsEmpty(ActiveSheet.Cells(1, colnum + 1).Value) Then<br />
           endchar = &#8220;)&#8221;<br />
       End If<br />
       CTLDataType = DataBaseProcs.CtlType(cellval, inTable, NewConn)</p>
<p>&#8216; Output to file<br />
       Print #1, cellval &#038; spacing &#038; CTLDataType &#038; endchar<br />
       colnum = colnum + 1<br />
    Loop<br />
    Close #1</p>
<p>    ActiveWorkbook.SaveAs Filename:=FileDir &#038; InLoadID &#038; &#8220;.dat&#8221;, FileFormat:=xlCSV, CreateBackup:=False<br />
&#8216;    retVal = Shell(&#8221;sqlldr **USER**/**PASSWORD**@**SID** control=&#8221; &#038; FileDir &#038; InLoadID &#038; &#8220;.ctl data= &#8221; &#038; FileDir &#038; InLoadID &#038; &#8220;.dat log=&#8221; &#038; FileDir &#038; InLoadID &#038; &#8220;.log&#8221;, vbNormalFocus)<br />
End Sub
</p></blockquote>
<!-- sphereit end --><span style="margin-bottom:40px; border-bottom:none;"><a class="iconsphere" title="Sphere: Related Content" onclick="return Sphere.Widget.search('http://myzenarcade.com/2009/02/24/oracle-tool-excel-writes-your-sqlloader-control-file/')" href="http://www.sphere.com/search?q=sphereit:http://myzenarcade.com/2009/02/24/oracle-tool-excel-writes-your-sqlloader-control-file/">Sphere: Related Content</a></span><br/><br/>]]></content:encoded>
			<wfw:commentRss>http://myzenarcade.com/2009/02/24/oracle-tool-excel-writes-your-sqlloader-control-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

