{"id":4518,"date":"2012-12-04T00:01:00","date_gmt":"2012-12-04T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2012\/12\/04\/use-oracle-odp-net-and-powershell-to-simplify-data-access\/"},"modified":"2012-12-04T00:01:00","modified_gmt":"2012-12-04T00:01:00","slug":"use-oracle-odp-net-and-powershell-to-simplify-data-access","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-oracle-odp-net-and-powershell-to-simplify-data-access\/","title":{"rendered":"Use Oracle ODP.NET and PowerShell to Simplify Data Access"},"content":{"rendered":"<p><strong>Summary:<\/strong> Guest blogger and Windows PowerShell Guru Klaus Schulte talks about using Oracle ODP.NET and Windows PowerShell to simplify data access to Oracle databases.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. It is early in the morning in Frankfurt, Germany, and the Scripting Wife and I just returned from Prague where we had a wonderful time visiting with one of the new Windows PowerShell MVPs David Moravec. David is a super nice person, and he took the time to show us around his lovely city. I must have taken nearly 500 pictures&mdash;won&rsquo;t know until I upload them to my portable USB hard drive. Anyway, we feel really blessed to have had the opportunity to spend the day with such an interesting person.<\/p>\n<p>And this brings our three-week tour to a close (in just a few hours). We have some time in the Frankfurt airport before our flights. This is a good thing because the Frankfurt airport has lots of things to do and to see. It is like a shopping mall with airplanes attached to it. Because I knew that things would be a bit confused today, I asked my good friend and PowerShell GURU Klaus Schulte to supply a guest post for today. With no further ado, here is Klaus.<\/p>\n<h2>How to use Windows PowerShell to query an Oracle database<\/h2>\n<p>By living in a networked world, with Internet access everywhere, information retrieval is often a snap. You don&rsquo;t need to go to the living room and search through encyclopedias or dictionaries any more to find information&mdash;clicks on the touchscreen of your smartphone may do the job in seconds! Right, everything has changed, but behind the nice-colored icons, most of the information retrieval is still relying on some old-fashioned techniques&mdash;called databases. At the company I work for we definitely know that at least this will not change in the next couple of years.<\/p>\n<p>In fact, it is crucial to get at some database information, even in scripts, to retrieve information regarding the current workflow, the status of individual tasks, and error messages indicating a flaw in the workflow.<\/p>\n<p>By using Windows Powershell and ADO.NET, we are in a comfortable situation that let us query a database on the fly to get the required piece of information necessary for further processing.<\/p>\n<p>Unlike Cmd.exe but like VBScript, we could use ADODB for that job, or we could rely on ADO.NET and the System.Data namespace to query databases. Even for our Oracle databases, the .NET Framework did support us by the Microsoft System.Data.OracleClient, which has been part of the .NET Framework ever since but now it has been marked as deprecated and will no longer be supported in future Framework versions starting with .NET Framework 4.<\/p>\n<p>Non-Microsoft products are available, of course, and a free Oracle version ODP.NET has been around for some years, too. But we always used the Microsoft provider because it has been part of the Framework anyway and it worked fine out of the box.<\/p>\n<p>But, nowadays, as most companies are migrating to 64-bit systems, another level of complexity has been added to the provider choice: You have to pay attention to the combination of installed Oracle clients and data providers on the machines your company is running because the Microsoft and the Oracle provider rely and cooperate with an installed Oracle client version on each workstation and this can be a 32-bit or a 64-bit client. You can&rsquo;t easily provide an application that works in both worlds &hellip; you have to know which operating system you are running!<\/p>\n<p>Some non-Microsoft products don&rsquo;t need the Oracle client installed and can communicate directly with Oracle.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;&nbsp;You can walk through this article using the unmanaged Oracle.DataAccess.dll without any changes (except for the name of the dll). And if you use the Microsoft System.Data.OracleClient you will also be able to follow me with very little effort! Even if you use another RDBMS, chances are that you can easily build an analogue scenario for your database.<\/p>\n<h3>Download and install the Oracle ODP.NET<\/h3>\n<p>You can download a complete package called ODAC ( Oracle Data Access Components ) from Oracle, which includes developer tools for Visual Studio, Data Provider for (ASP) .NET 4 and (ASP) .NET 2, Database Extensions for .NET 2, and Services for MTS, Provider for OLE DB, Objects for OLE, ODBC driver, SQL Plus, and the instant client.<\/p>\n<p>Everything can be installed via the Oracle Universal installer, which is part of the pack, too. I won&rsquo;t recommend using the ODBC driver unless you have to because it is the slowest connection method. OLE DB might deliver an acceptable performance for your applications, but if you can choose freely, the Oracle Data Provider for .NET should be your first choice.<\/p>\n<p>As I mentioned above, the Oracle Instant Client is part of the ODAC and there is one thing I want to point out here: You have to install an Oracle Client for each of data access method.<\/p>\n<p>Also, be aware that the standard Oracle Client may be a large piece of software! Depending on the functionality needed, you may have to dedicate over 500 MB on each workstation. The Instant Client is an improvement, which reduces the size of the client to about 100 MB as there are only a couple of binaries (DLL)&nbsp; delivered in this package, which can be copied to each workstation without the need of any further Setup. However, it only contains the most basic functionality where additional add-ons might be needed.<\/p>\n<p>A major problem is that depending on your software mix, it might be necessary to install the 32-bit and the 64-bit versions of the client, which is a challenge on its own, if you have to make both versions available on one machine.<\/p>\n<p>Another option that offers .NET access to the database is:&nbsp; Just use the Oracle Data Provider for .NET, which can be obtained as a separate download from Oracle called ODP.NET and is available in a 32- and 64-bit versions. This was the way I preferred to query our database up to now.<\/p>\n<p>A couple of weeks ago, Oracle released the public beta of an ODP.NET version that makes life much easier now.<\/p>\n<p>The brand new alpha version of the Oracle Managed DataAccess provider OPD.NET is available for <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/windows\/downloads\/odpmbeta-1696432.html\" target=\"_blank\">download at the Oracle .Net Developer center<\/a>. (You have to create an Oracle account for free, if you haven&rsquo;t already got one.)<\/p>\n<p>When the download is complete, just unzip the file ODP.NET_Managed_1120350_Beta.zip to a location like C:\\Oracle and start using the Oracle.ManagedDataAccess.dll.<\/p>\n<p>The good news is:<\/p>\n<ol>\n<li>ODP.NET runs on x32 and x64 Windows.<\/li>\n<li>You don&rsquo;t have to install an Oracle client.<\/li>\n<li>The size of ODP.NET is less than 7 MB.<\/li>\n<\/ol>\n<p>&nbsp;The bad news is:<\/p>\n<ol>\n<li>By now, there is no production version of ODP.NET available.<\/li>\n<li>The current beta has some limitations compared to unmanaged ODP.NET.<\/li>\n<li>You still need the unmanaged Oracle.ManagedDataAccessDTC.dll if you need to work with the Distributed Transaction Coordinator.<\/li>\n<\/ol>\n<p>These issues should be gone with the production version that should be available next year.<\/p>\n<p>We can use this DLLon Windows 7 and Windows Server 2008 or later with Microsoft .NET Framework 4 installed (the same requirements as Windows Powershell 3.0). Of course, it will be reasonable to have access to an Oracle database server (10g R2 or higher), too.<\/p>\n<p>Now we want to execute some SQL Server commands against database.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;&nbsp;If you don&rsquo;t have an Oracle database handy, you can download the free XE version (similar to SQL Server Express) and use the example schema <strong>hr<\/strong>, which is installed as part of the Setup procedure of the XE database. <a href=\"http:\/\/www.oracle.com\/technetwork\/products\/express-edition\/downloads\/index.html\" target=\"_blank\">Download the Oracle 11g R2 Database Express Edition<\/a>. (You have to create an Oracle account for free, if you haven&rsquo;t already got one.)<\/p>\n<h3>Import the Oracle.ManageDataAccess.dll<\/h3>\n<p>First, import this library. If you unzipped the dll to &ldquo;C:\\Oracle&rdquo; you can start with:<\/p>\n<p style=\"padding-left: 30px\">Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p>The next step is to create a connection to the database. Here you need to supply credentials to access the database and schema as well as a host and service name.<\/p>\n<p>Unlock the hr account and supply the password <strong>hr<\/strong> by using this technique: Open a console window, type <strong>sqlplus \/ as sysdba<\/strong> to connect to the locally running XE database, and if you are connected, type: <strong>alter user hr identified by hr account unlock;<\/strong><\/p>\n<p>&nbsp;You should be able to connect by the connection string: &#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection(&#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;)<\/p>\n<p>&nbsp;Next, you check if the connection can be opened!<\/p>\n<p>&nbsp;But, first, you should examine the <strong>$con<\/strong> object, as shown here:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;PS C:\\Users\\Schulte&gt; $con<\/p>\n<p style=\"padding-left: 30px\">&nbsp;ConnectionString&nbsp;&nbsp; : User Id=hr;Password=hr;Data Source=localhost\/XE<\/p>\n<p style=\"padding-left: 30px\">State&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Closed<\/p>\n<p style=\"padding-left: 30px\">ModuleName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ActionName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ClientId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ClientInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ConnectionTimeout&nbsp; : 15<\/p>\n<p style=\"padding-left: 30px\">Database&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">DatabaseName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">DatabaseDomainName :<\/p>\n<p style=\"padding-left: 30px\">HostName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">InstanceName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ServiceName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">DataSource&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : localhost\/XE<\/p>\n<p style=\"padding-left: 30px\">ServerVersion&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">StatementCacheSize : 0<\/p>\n<p style=\"padding-left: 30px\">Site&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">Container&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p>&nbsp;Interestingly, you can see that the properties except for the connection string are already preset: The standard connection timeout is <strong>15<\/strong> (seconds), the data source <strong>localhost\/XE<\/strong> is taken from the connection string, a statement cache size is preset to <strong>0<\/strong>, and the connection state is still <strong>closed<\/strong>.<\/p>\n<p>Let&rsquo;s open the connection now:<\/p>\n<p style=\"padding-left: 30px\">$con.open()<\/p>\n<p>If the database and listener are running on the local machine and the service XE is available to user <strong>hr<\/strong> with password <strong>hr<\/strong>, that command should work and inspecting the <strong>$con<\/strong> object again will reveal some changes, as shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $con<\/p>\n<p style=\"padding-left: 30px\">ConnectionString&nbsp;&nbsp; : User Id=hr;Data Source=localhost\/XE<\/p>\n<p style=\"padding-left: 30px\">State&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Open<\/p>\n<p style=\"padding-left: 30px\">ModuleName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ActionName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ClientId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ClientInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ConnectionTimeout&nbsp; : 15<\/p>\n<p style=\"padding-left: 30px\">Database&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">DatabaseName&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: XE<\/p>\n<p style=\"padding-left: 30px\">DatabaseDomainName :<\/p>\n<p style=\"padding-left: 30px\">HostName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : wdo-2907<\/p>\n<p style=\"padding-left: 30px\">InstanceName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : xe<\/p>\n<p style=\"padding-left: 30px\">ServiceName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : XE<\/p>\n<p style=\"padding-left: 30px\">DataSource&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : localhost\/XE<\/p>\n<p style=\"padding-left: 30px\">ServerVersion&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 11.2.0.2.0<\/p>\n<p style=\"padding-left: 30px\">StatementCacheSize : 40<\/p>\n<p style=\"padding-left: 30px\">Site&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">Container&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p>The properties <strong>DatabaseName<\/strong>, <strong>HostName<\/strong>, <strong>InstanceName<\/strong>, <strong>ServiceName<\/strong>, and <strong>ServerVersion<\/strong> have values now. And the <strong>StatementCacheSize<\/strong> has been updated to a value reported by the server, too.<\/p>\n<p>It is mandatory to catch errors here as it is somewhat likely that you won&rsquo;t get connected on the first try because you may have the credentials or other parts of the connection string wrong, or the listener or the database may not be running, or network problems might exist. We can never rely on a successful connect.<\/p>\n<p style=\"padding-left: 30px\">Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p style=\"padding-left: 30px\">try {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; $con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection(&#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; $con.open()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; &#8220;Connected to database: {0} running on host: {1} &#8211; Servicename: {2} &#8211; Serverversion: {3}&#8221; -f `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $con.DatabaseName, $con.HostName, $con.ServiceName, $con.ServerVersion<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">catch<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Write-Error (&#8220;Can&#8217;t open connection: {0}`n{1}&#8221; -f `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con.ConnectionString, $_.Exception.ToString())<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">finally<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; if ($con.State -eq &#8216;Open&#8217;) { $con.close() }<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p>Let&rsquo;s assume that we could successfully connect the database by using the connection string. Connecting is fine, but you usually want to do something else&mdash;like querying the database for some results! Whether the connection is open or not, you can ask the <strong>$con<\/strong> object to create a <strong>command<\/strong> object, as shown here:<\/p>\n<p style=\"padding-left: 30px\">$cmd=$con.CreateCommand()<\/p>\n<p>Or, you can create a new <strong>cmd<\/strong> object directly but with more writing effort:<\/p>\n<p style=\"padding-left: 30px\">$cmd=new-object Oracle.ManagedDataAccess.Client.OracleCommand<\/p>\n<p>Examining the <strong>$cmd<\/strong> object returns some interesting properties:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $cmd<\/p>\n<p style=\"padding-left: 30px\">AddRowid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">AddToStatementCache&nbsp;&nbsp;&nbsp; : True<\/p>\n<p style=\"padding-left: 30px\">ArrayBindCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">BindByName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">CommandTimeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Text<\/p>\n<p style=\"padding-left: 30px\">Connection&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Oracle.ManagedDataAccess.Client.OracleConnection<\/p>\n<p style=\"padding-left: 30px\">Transaction&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">DesignTimeVisible&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<\/p>\n<p style=\"padding-left: 30px\">FetchSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 131072<\/p>\n<p style=\"padding-left: 30px\">RowSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">InitialLOBFetchSize&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">InitialLONGFetchSize&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">UpdatedRowSource&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Both<\/p>\n<p style=\"padding-left: 30px\">Parameters&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {}<\/p>\n<p style=\"padding-left: 30px\">Notification&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">NotificationAutoEnlist : True<\/p>\n<p style=\"padding-left: 30px\">Site&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">Container&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p>The <strong>CommandType<\/strong> is <strong>Text<\/strong> by default meaning that you will be able to directly supply a select command.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;Other enumeration values are <strong>StoredProcedure<\/strong> and <strong>TableDirect<\/strong>.<\/p>\n<p><strong>CommandText<\/strong> will be the property where the text of the select command will be stored:<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText=&#8221;Select &#8216;Hello world!&#8217; Greeting from dual&#8221;<\/p>\n<p>Here we just produce a greeting message, which can run on any schema because it uses the build in table &ldquo;dual&rdquo;. There is just one piece missing: How do you execute the command?<\/p>\n<h3>Execute the command<\/h3>\n<p>You need a reader object to read the result set returned from the database. But it&rsquo;s crucial to have the connection open before you can execute the reader!<\/p>\n<p style=\"padding-left: 30px\">$con.Open()<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p>Once you have the <strong>$rdr<\/strong> object, you can call its read method to fetch the next data row, if any data is available, and if it returns a result, we can use, for example, the <strong>GetString<\/strong> member function to retrieve the <strong>n-th<\/strong> field of the returned resultset where <strong>n<\/strong> is an integer starting with <strong>0<\/strong>:<\/p>\n<p style=\"padding-left: 30px\">if ($rdr.Read()) {$rdr.GetString(0)}<\/p>\n<p>If this is all you need, we have to close the connection in the end!<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p>So, all in all, here are the easy steps ready for use now:<\/p>\n<p style=\"padding-left: 30px\">Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p style=\"padding-left: 30px\">$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection(&#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;)<\/p>\n<p style=\"padding-left: 30px\">$cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText=&#8221;Select &#8216;Hello world!&#8217; Greeting from dual&#8221;<\/p>\n<p style=\"padding-left: 30px\">$con.Open()<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">if ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $rdr.GetString(0)<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Hello world!<\/p>\n<p>&nbsp;<\/p>\n<p>WOW! We received an impressing sign of life from our database!&nbsp;Let&rsquo;s try something more difficult: Add two attributes to the output of our select statement, as shown here:<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText= @&#8221;<\/p>\n<p style=\"padding-left: 30px\">select<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intCount,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8216;Number_&#8217; || to_char(1) strCount,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; sysdate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datCount<\/p>\n<p style=\"padding-left: 30px\">from dual<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p>I love to enclose the whole query string in a so-called Windows Powershell <strong>here-string<\/strong>, which lets me keep the original formatting of the SQL Server statement even if it spans several rows! Just exchanging the previous select statement with the new statement results in the following:<\/p>\n<p style=\"padding-left: 30px\">Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p style=\"padding-left: 30px\">$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection(&#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;)<\/p>\n<p style=\"padding-left: 30px\">$cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText= @&#8221;<\/p>\n<p style=\"padding-left: 30px\">select<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intCount,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8216;Number_&#8217; || to_char(1) strCount,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; sysdate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datCount<\/p>\n<p style=\"padding-left: 30px\">from dual<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">$con.Open()<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">if ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $rdr.GetString(0)<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Ausnahme beim Aufrufen von &#8220;GetString&#8221; mit 1 Argument(en):&nbsp; &#8220;Die angegebene Umwandlung ist ung&uuml;ltig.&#8221;<\/p>\n<p style=\"padding-left: 30px\">In Zeile:15 Zeichen:5<\/p>\n<p style=\"padding-left: 30px\">+&nbsp;&nbsp;&nbsp;&nbsp; $rdr.GetString(0)<\/p>\n<p style=\"padding-left: 30px\">+&nbsp;&nbsp;&nbsp;&nbsp; ~~~~~~~~~~~~~~~~~<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : NotSpecified: (:) [], MethodInvocationException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : InvalidCastException<\/p>\n<p>&nbsp;My free translation for this error message is: Exception calling &ldquo;GetString&rdquo; with 1 argument(s): &ldquo;The conversion is invalid.&rdquo;<\/p>\n<p>What happened here? As our database has a well-elaborated type system, it refuses to convert the intCount value <strong>1<\/strong> implicitly to a string that is the type of data required to execute the statement:<\/p>\n<p style=\"padding-left: 30px\">$rdr.GetString(0)<\/p>\n<p>It says: <strong>GetString<\/strong>, not <strong>GetInteger<\/strong>, or something else more appropriate!<\/p>\n<p>What is &ldquo;more appropriate&rdquo;? By using Windows Powershell 3.0, you can have a look at the member function by using the new IntelliSense feature:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6558.hsg-12-4-12-3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6558.hsg-12-4-12-3.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>This is a great help if you are exploring non-Microsoft objects, and it accelerates typing and helps avoid typos, too. J OK, you may scroll down to find more candidates, or just try functions <strong>GetByte<\/strong> or <strong>GetDecimal<\/strong> at first sight. Let&rsquo;s try <strong>GetDecimal<\/strong>, shown here:<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">if ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $rdr.GetDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p>&nbsp;It worked! If you prefer to scroll down, you may find some more Oracle-specific <strong>GetOracle <\/strong>-functions in the box:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4503.hsg-12-4-12-4.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4503.hsg-12-4-12-4.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>As you won&rsquo;t find a <strong>GetOracleInteger<\/strong> function, I would definitely go for <strong>GetOracleDecimal<\/strong>, in this case. Let&rsquo;s see what we&rsquo;ll get now:<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">if ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsNull&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">BinData&nbsp;&nbsp;&nbsp; : {2, 193, 2, 0&#8230;}<\/p>\n<p style=\"padding-left: 30px\">IsInt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<\/p>\n<p style=\"padding-left: 30px\">IsPositive : True<\/p>\n<p style=\"padding-left: 30px\">IsZero&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">Format&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">Value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 1<\/p>\n<p>It worked somehow, but we get more information than expected and needed. The expected result is represented by the value property. If you want to know more about the object returned by <strong>GetOracleDecimal<\/strong>, I would suggest to store it in a variable <strong>$result<\/strong> and expect it later on to find out that it is of type <strong>OracleDecimal<\/strong>, as shown here:<\/p>\n<p>&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $result.GetType()<\/p>\n<p style=\"padding-left: 30px\">IsPublic IsSerial Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">True&nbsp;&nbsp;&nbsp;&nbsp; True&nbsp;&nbsp;&nbsp;&nbsp; OracleDecimal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.ValueType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>And it has some properties, including the interesting <strong>value<\/strong> property:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $result<\/p>\n<p style=\"padding-left: 30px\">IsNull&nbsp;&nbsp;&nbsp; &nbsp;: False<\/p>\n<p style=\"padding-left: 30px\">BinData&nbsp;&nbsp;&nbsp; : {2, 193, 2, 0&#8230;}<\/p>\n<p style=\"padding-left: 30px\">IsInt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<\/p>\n<p style=\"padding-left: 30px\">IsPositive : True<\/p>\n<p style=\"padding-left: 30px\">IsZero&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">Format&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">Value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 1<\/p>\n<p>&nbsp;And it has a couple of member functions associated to it:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; TypeName: Oracle.ManagedDataAccess.Types.OracleDecimal<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">CompareTo&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; int CompareTo(System.Object obj), int IComparable.CompareTo(System.Object obj)<\/p>\n<p style=\"padding-left: 30px\">Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; bool Equals(System.Object obj)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetHashCode Method&nbsp;&nbsp;&nbsp;&nbsp; int GetHashCode()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetSchema&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetType&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; type GetType()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ReadXml&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToByte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; byte ToByte()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToDouble&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; double ToDouble()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToInt16&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; int16 ToInt16()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToInt32&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; int ToInt32()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToInt64&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; long ToInt64()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToSingle&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; float ToSingle()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToString&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; string ToString()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">WriteXml&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">BinData&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; byte[] BinData {get;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Format&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; string Format {get;set;}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsInt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; bool IsInt {get;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsNull&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; bool IsNull {get;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsPositive&nbsp; Property&nbsp;&nbsp; bool IsPositive {get;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsZero&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; bool IsZero {get;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; decimal Value {get;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>Well, it is obvious that we could use the <strong>To&hellip;<\/strong> functions to convert the resulting decimal value to some other sub datatypes.<\/p>\n<p>I won&rsquo;t discuss further details here, but you may be asking yourself this: Why do we have to deal with this proprietary <strong>OracleDecimal<\/strong> type instead of just using the simple and straight forward <strong>Decimal<\/strong> type? Well, there is one reason in the world of databases that is incompatible to the type system of most other programming or script languages and always requires special treatment: Null values!<\/p>\n<h3>Using special Oracle data types<\/h3>\n<p>&nbsp;In most traditional programming languages special functions have been introduced to test for nullable values. That&rsquo;s where it makes perfectly sense to use the special Oracle data types even if it is a bit more effort to extract the value!<\/p>\n<p>That said, our new query does work for us, but hey, we only received one value where three values should be available: <strong>intCount<\/strong>, <strong>strCount<\/strong>, and <strong>datCount<\/strong>!<\/p>\n<p>The solution is rather obvious so we can simply add two statements after the <strong>GetOracleDecimal<\/strong> call:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p style=\"padding-left: 30px\">$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection(&#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;)<\/p>\n<p style=\"padding-left: 30px\">$cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText= @&#8221;<\/p>\n<p style=\"padding-left: 30px\">select<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intCount,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8216;Number_&#8217; || to_char(1) strCount,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; sysdate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datCount<\/p>\n<p style=\"padding-left: 30px\">from dual<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">$con.Open()<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">if ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $intCount=$rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $strCount=$rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $datCount=$rdr.GetOracleDate(2)<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">&#8220;Resultset: {0}, {1}, {2}&#8221; -f $intCount.Value, $strCount.Value, $datCount.Value<\/p>\n<p style=\"padding-left: 30px\">Resultset: 1, Number_1, 15.11.2012 13:31:51<\/p>\n<p>Wonderful! We can query rather complex Oracle result sets now! But there&rsquo;s only one row that we have retrieved from the database by now. What about receiving several rows as result of a query? Let&rsquo;s change the select command to something more useful, as shown here:<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText= @&#8221;<\/p>\n<p style=\"padding-left: 30px\">with resultset (intCount, strCount, datCount) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp; select 1 intCount, &#8216;Number_&#8217; || to_char(1) strCount, sysdate datCount<\/p>\n<p style=\"padding-left: 30px\">&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select r.intCount+1, &#8216;Number_&#8217; || to_char(intCount+1), sysdate+intCount+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; from resultset r<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; where r.intCount &lt; 10<\/p>\n<p style=\"padding-left: 30px\">&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">)<\/p>\n<p style=\"padding-left: 30px\">select * from resultset<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p>You don&rsquo;t have to completely understand this recursive select statement by using a <strong>recursive with<\/strong> clause according to modern ANSI SQL, but it does produces the same output as the previous select if you exchange the constant 10 by 1. If you don&rsquo;t, it produces 10 lines of output increasing the values by one for each row:<\/p>\n<p>&nbsp;<\/p>\n<table style=\"width: 291px\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>INTCOUNT<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>STRCOUNT<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>DATCOUNT<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>1<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_1<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>15.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>2<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_2<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>17.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>3<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_3<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>18.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>4<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_4<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>19.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>5<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_5<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>20.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>6<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_6<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>21.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>7<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_7<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>22.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>8<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_8<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>23.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>9<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_9<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>24.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>10<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>Number_10<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>25.11.2012 13:40<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>The easiest way to reproduce this kind of output with our little Windows Powershell script is: Output the content of the three count variables inside the <strong>$rdr.read<\/strong> -script block, and exchange the <strong>if<\/strong> statement with a <strong>while<\/strong> statement, as shown here:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;PS C:\\Users\\Schulte&gt; Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection(&#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;)<\/p>\n<p style=\"padding-left: 30px\">$cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText= @&#8221;<\/p>\n<p style=\"padding-left: 30px\">with resultset (intCount, strCount, datCount) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp; select 1 intCount, &#8216;Number_&#8217; || to_char(1) strCount, sysdate datCount<\/p>\n<p style=\"padding-left: 30px\">&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select r.intCount+1, &#8216;Number_&#8217; || to_char(intCount+1), sysdate+intCount+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; from resultset r<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; where r.intCount &lt; 10<\/p>\n<p style=\"padding-left: 30px\">&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">)<\/p>\n<p style=\"padding-left: 30px\">select * from resultset<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">$con.Open()<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $intCount=$rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $strCount=$rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $datCount=$rdr.GetOracleDate(2)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &#8220;{0,3}, {1,10}, {2}&#8221; -f $intCount.Value, $strCount.Value, $datCount.Value<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 1,&nbsp;&nbsp; Number_1, 15.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 2,&nbsp;&nbsp; Number_2, 17.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 3,&nbsp;&nbsp; Number_3, 18.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 4,&nbsp;&nbsp; Number_4, 19.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 5,&nbsp;&nbsp; Number_5, 20.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 6,&nbsp;&nbsp; Number_6, 21.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 7,&nbsp;&nbsp; Number_7, 22.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 8,&nbsp;&nbsp; Number_8, 23.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp; 9,&nbsp;&nbsp; Number_9, 24.11.2012 13:49:08<\/p>\n<p style=\"padding-left: 30px\">&nbsp;10,&nbsp; Number_10, 25.11.2012 13:49:08<\/p>\n<p>&nbsp;That was a snap!<\/p>\n<p>&nbsp;We are just missing the header line:<\/p>\n<table style=\"width: 291px\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>INTCOUNT<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"83\">\n<p>STRCOUNT<\/p>\n<\/td>\n<td valign=\"top\" nowrap=\"nowrap\" width=\"125\">\n<p>DATCOUNT<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Of course, we could add this in a one liner by using a constant string, which is not the way I would like to do that! I would prefer to get this column header information from the database and in fact the data reader <strong>$rdr<\/strong> can query this information with a call to the GetSchemaTable() method, as shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $rdr.GetSchemaTable()<\/p>\n<p style=\"padding-left: 30px\">ColumnName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : INTCOUNT<\/p>\n<p style=\"padding-left: 30px\">ColumnOrdinal&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">ColumnSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 22<\/p>\n<p style=\"padding-left: 30px\">NumericPrecision : 38<\/p>\n<p style=\"padding-left: 30px\">NumericScale&nbsp;&nbsp;&nbsp;&nbsp; : 127<\/p>\n<p style=\"padding-left: 30px\">IsUnique&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">IsKey&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">IsRowID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">BaseColumnName&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">BaseSchemaName&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">BaseTableName&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">DataType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : System.Decimal<\/p>\n<p style=\"padding-left: 30px\">ProviderType&nbsp;&nbsp;&nbsp;&nbsp; : 107<\/p>\n<p style=\"padding-left: 30px\">AllowDBNull&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<\/p>\n<p style=\"padding-left: 30px\">IsAliased&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<\/p>\n<p style=\"padding-left: 30px\">IsByteSemantic&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">IsExpression&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">IsHidden&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">IsReadOnly&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<\/p>\n<p style=\"padding-left: 30px\">IsLong&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ColumnName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : STRCOUNT<\/p>\n<p style=\"padding-left: 30px\">ColumnOrdinal&nbsp;&nbsp;&nbsp; : 1<\/p>\n<p style=\"padding-left: 30px\">ColumnSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 47<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&hellip; <em>output abbreviated<\/em> &hellip;<\/p>\n<p>Along with a whole bunch of other valuable information about our data columns, we can access the <strong>ColumnName<\/strong> property:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $rdr.GetSchemaTable() | select ColumnName<\/p>\n<p style=\"padding-left: 30px\">ColumnName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">INTCOUNT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">STRCOUNT&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">DATCOUNT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>&nbsp;If we can retrieve the column names, we may come up with a nice header line after some formatting:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&#8220;{0,10}, {1,10}, {2,8}&#8221; -f ($rdr.GetSchemaTable() | select ColumnName -ExpandProperty ColumnName)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$con.Open()<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">&#8220;{0,10}, {1,10}, {2,8}&#8221; -f ($rdr.GetSchemaTable() | select ColumnName -ExpandProperty ColumnName)<\/p>\n<p style=\"padding-left: 30px\">while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $intCount=$rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $strCount=$rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $datCount=$rdr.GetOracleDate(2)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &#8220;{0,10}, {1,10}, {2}&#8221; -f $intCount.Value, $strCount.Value, $datCount.Value<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp; INTCOUNT,&nbsp;&nbsp; STRCOUNT, DATCOUNT<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1,&nbsp;&nbsp; Number_1, 15.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2,&nbsp;&nbsp; Number_2, 17.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3,&nbsp;&nbsp; Number_3, 18.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4,&nbsp;&nbsp; Number_4, 19.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5,&nbsp;&nbsp; Number_5, 20.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6,&nbsp;&nbsp; Number_6, 21.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7,&nbsp;&nbsp; Number_7, 22.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,&nbsp;&nbsp; Number_8, 23.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9,&nbsp;&nbsp; Number_9, 24.11.2012 14:09:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10,&nbsp; Number_10, 25.11.2012 14:09:32<\/p>\n<p>&nbsp;<\/p>\n<p>This is quite OK, but it&rsquo;s not the way we want to do this in Windows Powershell.&nbsp;We would prefer to have objects here and let Windows Powershell do all the formatting for us. Let&rsquo;s change the read block again:<\/p>\n<p style=\"padding-left: 30px\">$con.Open()<\/p>\n<p style=\"padding-left: 30px\">$rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">$columnNames=$rdr.GetSchemaTable() | Select-Object -ExpandProperty ColumnName<\/p>\n<p style=\"padding-left: 30px\">$resultSet=@()<\/p>\n<p style=\"padding-left: 30px\">while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $result=New-Object object<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[0] -NotePropertyValue $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[1] -NotePropertyValue $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[2] -NotePropertyValue $rdr.GetOracleDate(2)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet += $result<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">$con.Close()<\/p>\n<p style=\"padding-left: 30px\">$resultSet | Format-Table -AutoSize<\/p>\n<p>Executing this will result in a nicely formatted object output:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; D:\\Script\\Query_Oracle5.ps1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">INTCOUNT STRCOUNT&nbsp; DATCOUNT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8211; &#8212;&#8212;&#8211;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_1&nbsp; 11\/15\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_2&nbsp; 11\/17\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_3&nbsp; 11\/18\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_4&nbsp; 11\/19\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_5&nbsp; 11\/20\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">6&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number_6&nbsp; 11\/21\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_7&nbsp; 11\/22\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_8&nbsp; 11\/23\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_9&nbsp; 11\/24\/2012 14:31:08<\/p>\n<p style=\"padding-left: 30px\">10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number_10 11\/25\/2012 14:31:08<\/p>\n<p>Best of all: You can even use <strong>Out &ndash;GridView<\/strong> instead of <strong>Format-Table<\/strong> &nbsp;<strong>&ndash;AutoSize<\/strong>, if you want to display the data even more nicely. Additionally, the filtering and sorting capabilities of a data grid view are now for free.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3617.newgraphic1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3617.newgraphic1.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>To get this result in a much easier way (less to write), use can also use the following script:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p style=\"padding-left: 30px\">$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection(&#8220;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;)<\/p>\n<p style=\"padding-left: 30px\">$cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">$cmd.CommandText= @&#8221;<\/p>\n<p style=\"padding-left: 30px\">with resultset (intCount, strCount, datCount) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp; select 1 intCount, &#8216;Number_&#8217; || to_char(1) strCount, sysdate datCount<\/p>\n<p style=\"padding-left: 30px\">&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select r.intCount+1, &#8216;Number_&#8217; || to_char(intCount+1), sysdate+intCount+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; from resultset r<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; where r.intCount &lt; 10<\/p>\n<p style=\"padding-left: 30px\">&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">)<\/p>\n<p style=\"padding-left: 30px\">select * from resultset<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">$da=New-Object Oracle.ManagedDataAccess.Client.OracleDataAdapter($cmd);<\/p>\n<p style=\"padding-left: 30px\">$resultSet=New-Object System.Data.DataTable<\/p>\n<p style=\"padding-left: 30px\">[void]$da.fill($resultSet)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$resultSet | Format-Table -AutoSize<\/p>\n<p>&nbsp;The result is identical, except the formatting of the INTCOUNT column:<\/p>\n<p style=\"padding-left: 30px\">INTCOUNT STRCOUNT&nbsp; DATCOUNT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8211; &#8212;&#8212;&#8211;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 Number_1&nbsp; 15.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 Number_2&nbsp; 17.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 Number_3&nbsp; 18.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4 Number_4&nbsp; 19.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5 Number_5&nbsp; 20.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6 Number_6&nbsp; 21.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7 Number_7&nbsp; 22.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8 Number_8&nbsp; 23.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9 Number_9&nbsp; 24.11.2012 14:41:32<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10 Number_10 25.11.2012 14:41:32<\/p>\n<p>I did exchange the data reader with a data adapter, which has a <strong>Fill<\/strong> method that can automatically populate a dataset or data table with the results of the select statement. This is at least a timesaver writing the script code. A rather interesting question came to mind now: Is it a timesaver regarding performance, too? Well, we probably should do some testing now. But measuring the execution time of the select command is most likely faulty if we just execute one select. Maybe 10 selects would provide a better measurement basis and retrieving more than 10 rows, maybe 100, might be better, too. To do so, we are getting a bit more Windows Powershell-stylish now and encapsulate the two scripts in functions. We omit the <strong>Format-Table<\/strong> statement in the end and return the whole <strong>$resultSet<\/strong> as result of the new functions. But we should definitely consider some more changes.<\/p>\n<p>The new versions of the script might look even better if we parameterize the select statement and probably the connection string, too!<\/p>\n<p>Before we do this, I have to admit that even then, we have still some things to consider that would be nice to have: Querying a database using a fixed select statement might be more or less &ldquo;sub optimal&rdquo;. Additionally, the use of a constant connection string is not the best solution. There are some further topics that could have been addressed like using parameters in select statements, executing queries that don&rsquo;t return result sets or issuing other statements that don&rsquo;t select data at all. Nevertheless, we&rsquo;ll concentrate on the connection string and the select command here, and ignore other potential improvements.<\/p>\n<p>I added rudimentary error checking and a very simple checking on both input parameters, too. We just set the whole function inside a try-catch-finally block to catch and report any errors that are likely to happen during database operations.<\/p>\n<p>The &ldquo;ValidateScript&rdquo; instruction is used to check that the connection string includes at least the &ldquo;data source&rdquo; property and that the select string contains the word &ldquo;select.&rdquo; Additionally, I made both parameters mandatory without supplying defaults, which wouldn&rsquo;t make too much sense in my opinion.<\/p>\n<p>Finally, we have the following script featuring two functions Get-OracleResultRdr and Get-OracleResultDa:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Add-Type -Path &ldquo;C:\\Oracle\\Oracle.ManagedDataAccess.dll&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">function Get-OracleResultRdr<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bdata source\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$conString,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bselect\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet=@()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; try {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection($conString)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd.CommandText= $sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con.Open()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames=$rdr.GetSchemaTable() | Select-Object -ExpandProperty ColumnName<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = New-Object PsObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[0] -NotePropertyValue $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[1] -NotePropertyValue $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[2] -NotePropertyValue $rdr.GetOracleDate(2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet += $result<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } catch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Error ($_.Exception.ToString())<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } finally {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($con.State -eq &#8216;Open&#8217;) { $con.close() }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">function Get-OracleResultDa<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bdata source\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$conString,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bselect\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet=@()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; try {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection($conString)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd.CommandText= $sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $da=New-Object Oracle.ManagedDataAccess.Client.OracleDataAdapter($cmd);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet=New-Object System.Data.DataTable<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [void]$da.fill($resultSet)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } catch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Error ($_.Exception.ToString())<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } finally {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($con.State -eq &#8216;Open&#8217;) { $con.close() }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\"># Test data for functions<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$conString=&#8221;User Id=hr;Password=hr;Data Source=localhost\/XE&#8221;<\/p>\n<p style=\"padding-left: 30px\">$sqlString=@&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; with resultset (intCount, strCount, datCount) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select 1 intCount, &#8216;Number_&#8217; || to_char(1) strCount, sysdate datCount<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select r.intCount+1, &#8216;Number_&#8217; || to_char(intCount+1), sysdate+intCount+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from resultset r<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where r.intCount &lt; 1000<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select * from resultset<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Get-OracleResultRdr $conString $sqlString<\/p>\n<p style=\"padding-left: 30px\">Get-OracleResultDa&nbsp; $conString $sqlString<\/p>\n<p>&nbsp;I mentioned above that it might be necessary to do some repetitions if you want to measure the execution time of each command to get a feeling for the performance of both procedures, but, in fact, it is rather obvious that the first command lasts longer than the second does. However, measure the time for 10 loops of each command now. Instead of the last two lines, do the following:<\/p>\n<p style=\"padding-left: 30px\">$timeRdr = Measure-Command {1..10 | %{Get-OracleResultRdr $conString $sqlString}}<\/p>\n<p style=\"padding-left: 30px\">$timeDa&nbsp; = Measure-Command {1..10 | %{Get-OracleResultDa&nbsp; $conString $sqlString}}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8220;Time used by the DataReader : &#8221; + $timeRdr.TotalSeconds\/10<\/p>\n<p style=\"padding-left: 30px\">&#8220;Time used by the dataAdapter: &#8221; + $timeDa.TotalSeconds \/10<\/p>\n<p>The results are:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; D:\\Script\\Query_Oracle8.ps1<\/p>\n<p style=\"padding-left: 30px\">Time used by the DataReader : 1.46688318<\/p>\n<p style=\"padding-left: 30px\">Time used by the dataAdapter: 0.0084921<\/p>\n<p>Unbelievable! &nbsp;And definitely wrong, as I can tell you from my experience! 8.4921[ms] is not a realistic time.<\/p>\n<p>But I can explain to you that each database relies on heavy, well elaborated, and highly tuned caching algorithms that prevent a reasonable timing if you loop through the same statement. The statement is preparsed and cached, the previously calculated execution plan is used again and if result set caching is available, the execution may be skipped at all, and the old result set will just be returned to the client.<\/p>\n<p>So, we will have to clear the buffer cache and shared pool before we can execute each statement once, if we really would like to have reasonable timing data for at least one execution of each statement. I&rsquo;ll open a <strong>sqlplus<\/strong> command window and execute the two commands now before running each of the functions:<\/p>\n<p style=\"padding-left: 30px\">SQL&gt; alter system flush buffer_cache;<\/p>\n<p style=\"padding-left: 30px\">System altered.<\/p>\n<p style=\"padding-left: 30px\">SQL&gt; alter system flush shared_pool;<\/p>\n<p style=\"padding-left: 30px\">System altered.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; Measure-Command {Get-OracleResultRdr $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 269<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 22693179<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2,62652534722222E-05<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,000630366083333333<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,037821965<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2,2693179<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 2269,3179<\/p>\n<p style=\"padding-left: 30px\">SQL&gt; alter system flush buffer_cache;<\/p>\n<p style=\"padding-left: 30px\">System altered.<\/p>\n<p style=\"padding-left: 30px\">SQL&gt; alter system flush shared_pool;<\/p>\n<p style=\"padding-left: 30px\">System altered.<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; Measure-Command {Get-OracleResultDa $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 292<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2922746<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 3,38280787037037E-06<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 8,11873888888889E-05<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,00487124333333333<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,2922746<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 292,2746<\/p>\n<p>&nbsp;These data are more realistic! But still the data adapter is ready in 0.3 seconds whereas the reader operation lasts 2.27 seconds. Is it real that the data adapter received the results 7 to 8 times faster than the reader? Very unlikely, I would say.<\/p>\n<p>So, let&rsquo;s try to tune the reader, or at least find out if it is really that slow. I will flush the database cache each time before I test the statement. We can definitely expect that most of the time if used inside the loop:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = New-Object PsObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[0] -NotePropertyValue $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[1] -NotePropertyValue $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[2] -NotePropertyValue $rdr.GetOracleDate(2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet += $result<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p>So, let&rsquo;s read the data without processing them at all.<\/p>\n<p style=\"padding-left: 30px\">while ($rdr.Read()) {}<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,2412746<\/p>\n<p>&nbsp;<\/p>\n<p>That&rsquo;s far better now. Let&rsquo;s see what happens if we include the <strong>GetOracle&lt;type&gt;<\/strong> methods inside the loop. It may be that they are slowing the operation down:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $intCount = $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $strCount = $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $datCount = $rdr.GetOracleDate(2)&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,2379125<\/p>\n<p>Well, this is not too bad at all! It seems to be even faster than the preceding measurement, which is, of course, hardly possible. It is more or less a result of inaccurate timing for such fast operations. But, in general, it indicated that the behavior didn&rsquo;t change significantly.<\/p>\n<p>Even if we consume the data, we are still pretty fast getting at the results! So what else could be the reason why?<\/p>\n<h2>Object creation<\/h2>\n<p>Let&rsquo;s add the object creation to the scenario:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = New-Object PsObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $intCount = $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $strCount = $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $datCount = $rdr.GetOracleDate(2)&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,2718845<\/p>\n<p>No remarkable changes, too! Let&rsquo;s add up the newly created (empty) object to form the result set:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = New-Object PsObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $intCount = $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $strCount = $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $datCount = $rdr.GetOracleDate(2)&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet += $result<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,407326<\/p>\n<p>No significant change, but the objects were empty!&nbsp;Falling back to the previous scenario: &nbsp;Let&rsquo;s add properties to the <strong>$result <\/strong>object and don&rsquo;t add them up in <strong>$resultset<\/strong>:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = New-Object PsObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[0] -NotePropertyValue $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[1] -NotePropertyValue $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$result | Add-Member -NotePropertyName $columnNames[2] -NotePropertyValue $rdr.GetOracleDate(2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">1,9345301<\/p>\n<p>&nbsp;That&rsquo;s it! At least partially. We found the slow operation: Adding members to the <strong>PsCustomObject<\/strong> seems to be very time consuming.<\/p>\n<p>Comparing it to the original 2.27[s] we can imagine that the time to add up the <strong>$results<\/strong> to the <strong>$resultset<\/strong> adds another 0.3 seconds penalty to the execution time and you might have already observed it: We can get rid of this extra time.<\/p>\n<p>In fact, it is not necessary to build the <strong>$resultset<\/strong> ourselves, we can emit each <strong>$result<\/strong> inside the loop and let Windows Powershell organize the stream of results! This would be an improvement that Windows Powershell offers for free! It is less coding and less failure and as we have seen here less execution time! So, the next thing we will do is: Eliminate the variable <strong>$resultset<\/strong> und return <strong>$result<\/strong> in each iteration:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = New-Object PsObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[0] -NotePropertyValue $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[1] -NotePropertyValue $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result | Add-Member -NotePropertyName $columnNames[2] -NotePropertyValue $rdr.GetOracleDate(2)&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p>Back to the main insight now: Adding members to our object is slowing the function down! The final question is: Do we have alternative ways to build object and are they faster? Well, we can build objects like this in Windows Powershell:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$result = &#8220;&#8221; | Select-Object $columnNames<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result.$($columnNames[0]) = $rdr.GetOracleDecimal(0)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result.$($columnNames[1]) = $rdr.GetOracleString(1)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result.$($columnNames[2]) = $rdr.GetOracleDate(2)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p>Surprisingly, this makes a big difference:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,3962451<\/p>\n<p>With Windows Powershell 3.0, you can also do it that way:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = New-Object psobject -Property @{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames[0] =&nbsp; $rdr.GetOracleDecimal(0);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames[1] =&nbsp; $rdr.GetOracleString(1);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames[2] =&nbsp; $rdr.GetOracleDate(2);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,7647542<\/p>\n<p>&nbsp;<\/p>\n<p>This seems to make a difference, too. It is still faster than <strong>Add-Member<\/strong>, but slower than the second solution &hellip; at least in this case.&nbsp;But wait! There is still another new solution available in Windows Powershell 3.0.&nbsp;We have the new [pscustomobject] type accelerator available now:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = [pscustomobject] @{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames[0] =&nbsp; $rdr.GetOracleDecimal(0);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames[1] =&nbsp; $rdr.GetOracleString(1);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames[2] =&nbsp; $rdr.GetOracleDate(2);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,373167<\/p>\n<p>WOW! The fastest solution so far&mdash;it may be a tie between this and the second solution because we can&rsquo;t know exactly if the timing is good enough.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;&nbsp;I could also eliminate the assignment to <strong>$result<\/strong> and return the object directly in the last two cases, which won&rsquo;t change the execution much. I just left it there for a better comparison to the first two solutions where we have to use the <strong>$result<\/strong> variable.<\/p>\n<p>The last thing I want to do now is to generalize the solution a little further! We still have used a special query up to now that returns three values in each row with fixed data types: <strong>OracleDecimal<\/strong>, <strong>OracleString<\/strong>, and <strong>OracleDate<\/strong>.<\/p>\n<p>This is very special and the question arises if we can modify the solution further to accept other types of data and more or less than three columns per row. Of course, we can but as a constructor of a [pscustomobject] with variable initial values is not available, can we still profit the fastest solution or will we have to go back to the <strong>Add-Member<\/strong> solution, which is very slow?<\/p>\n<p>Another problem is the usage of highly specialized type dependent <strong>GetOracle&lt;type&gt;<\/strong> functions that require us to know the type of object that is returned from the database. It would be possible to use these functions if we evaluate the data returned from the call to <strong>$rdr.GetSchemaTable()<\/strong>, where this information is part of the row description:<\/p>\n<p style=\"padding-left: 30px\">[DBG]: PS C:\\Users\\Schulte&gt;&gt; $rdr.GetSchemaTable().rows[0].Datatype.name<\/p>\n<p style=\"padding-left: 30px\">Decimal<\/p>\n<p style=\"padding-left: 30px\">[DBG]: PS C:\\Users\\Schulte&gt;&gt; $rdr.GetSchemaTable().rows[1].Datatype.name<\/p>\n<p style=\"padding-left: 30px\">String<\/p>\n<p style=\"padding-left: 30px\">[DBG]: PS C:\\Users\\Schulte&gt;&gt; $rdr.GetSchemaTable().rows[2].Datatype.name<\/p>\n<p style=\"padding-left: 30px\">DateTime<\/p>\n<p>But even if we had the type information, we would further have to use this information in a switch statement to retrieve the function call that is appropriate for the current field type. This is not fun!&nbsp;But wait, there is an easier way out! We can use the type neutral function:<\/p>\n<p style=\"padding-left: 30px\">[DBG]: PS C:\\Users\\Schulte&gt;&gt; $rdr.GetOracleValue<\/p>\n<p style=\"padding-left: 30px\">OverloadDefinitions&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">System.Object GetOracleValue(int i)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>This function doesn&rsquo;t depend on the type and returns an object.<\/p>\n<p>Putting it all together again, we can build a hashtable as our <strong>$result<\/strong> object that is composed of the column names and the corresponding values that we will retrieve in looping through the fields returned in the result set. Nicely enough, the field count is a property of the data reader:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result=@{}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0..($rdr.FieldCount-1) | %{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result.Add($columnNames[$_], $rdr.GetOracleValue($_))<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [pscustomobject]$result<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p>&nbsp;<\/p>\n<p>Returning a <strong>pscustomobject<\/strong> based on the hashtable <strong>$result<\/strong> works. This way we can use the fast constructor but have a variable initialization. Sounds fine, but hey, the result isn&rsquo;t that cute. In fact, we are back to where we started from: We have a time of over 2 seconds again.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; Measure-Command {Get-OracleResultRdr $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2,1450785<\/p>\n<p>A little additional overhead would be OK, if we can generalize queries. But is it really true that we are back to where we started from? I really thought so at first but investigating things further I discovered that the loop construct followed by the pipe is quite slow.<\/p>\n<p>Exchanging it with o for-loop returns better results:<\/p>\n<p>&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result=@{}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ($i=0; $i -lt $rdr.FieldCount; $i++) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 0..($rdr.FieldCount-1) | %{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result.Add($columnNames[$i], $rdr.GetOracleValue($i))<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [pscustomobject]$result<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; Measure-Command {Get-OracleResultRdr $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0,5363667<\/p>\n<p>&nbsp;<\/p>\n<p>This is quite acceptable for a generalized solution! Again, it wasn&rsquo;t a fault of the database that returned the results too slow, it was a problem with my script that slowed things down. Something to remember!<\/p>\n<p>If you are not convinced that it really does what it is supposed to do, we can supply some alternative queries just to present the results. Here is result of a query that returns the Fibonacci numbers and the depth level of the recursion (or just a counter if you prefer that ).<\/p>\n<p>The Fibonacci numbers are defined by Fib(0) = 0; fib(1) = 1; fib(n) = fib(n-1)+fib(n-2) for n &gt; 1<\/p>\n<p>In easy words: Start with two numbers 0 and 1. Calculate the next number by adding the last two numbers: 0, 1, (0+1)=1, (1+1)=2, (1+2)=3, (2+3)=5, (3+5)=8, &hellip;<\/p>\n<p>&nbsp;We could do this very easily in Windows Powershell with a recursive function:&nbsp;<\/p>\n<p style=\"padding-left: 30px\">function fibonacci($n)<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; if&nbsp;&nbsp;&nbsp;&nbsp; ($n -eq 0) {0}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; elseif ($n -eq 1) {1}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; {$(fibonacci($n-1))+$(fibonacci($n-2))}<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\"># produce some test values<\/p>\n<p style=\"padding-left: 30px\">0..20 | %{ fibonacci $_}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;The results are:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">0<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">3<\/p>\n<p style=\"padding-left: 30px\">5<\/p>\n<p style=\"padding-left: 30px\">8<\/p>\n<p style=\"padding-left: 30px\">13<\/p>\n<p style=\"padding-left: 30px\">21<\/p>\n<p style=\"padding-left: 30px\">34<\/p>\n<p style=\"padding-left: 30px\">55<\/p>\n<p style=\"padding-left: 30px\">89<\/p>\n<p style=\"padding-left: 30px\">144<\/p>\n<p style=\"padding-left: 30px\">233<\/p>\n<p style=\"padding-left: 30px\">377<\/p>\n<p style=\"padding-left: 30px\">610<\/p>\n<p style=\"padding-left: 30px\">987<\/p>\n<p style=\"padding-left: 30px\">1597<\/p>\n<p style=\"padding-left: 30px\">2584<\/p>\n<p style=\"padding-left: 30px\">4181<\/p>\n<p>You may notice that calculating the last values takes a noticeable amount of time. Let&rsquo;s do a quick check to unveil the number of recursive calls used to calculate the results and do an additional call to the Fibonacci function to see how much time we did spent to get at the results:<\/p>\n<p style=\"padding-left: 30px\">function fibonacci($n)<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $global:calls++<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; if&nbsp;&nbsp;&nbsp;&nbsp; ($n -eq 0) {0}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; elseif ($n -eq 1) {1}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; {$(fibonacci($n-1))+$(fibonacci($n-2))}<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\"># produce some test values<\/p>\n<p style=\"padding-left: 30px\">0..19 | %{ $calls=0; &#8220;Fibonacci ({0,2}) = {1,5} &#8212; {2,5} recursive calls in {3,-9} seconds&#8221; `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; -f $_, (fibonacci $_), $calls, (Measure-Command {fibonacci $_}).TotalSeconds}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 0) =&nbsp;&nbsp;&nbsp;&nbsp; 0 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 1 recursive calls in 0,0001971 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 1) =&nbsp;&nbsp;&nbsp;&nbsp; 1 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 1 recursive calls in 7,33E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 2) =&nbsp;&nbsp;&nbsp;&nbsp; 1 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 3 recursive calls in 0,0001956 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 3) =&nbsp;&nbsp;&nbsp;&nbsp; 2 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 5 recursive calls in 0,0003013 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 4) =&nbsp;&nbsp;&nbsp;&nbsp; 3 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 9 recursive calls in 0,000552&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 5) =&nbsp;&nbsp;&nbsp;&nbsp; 5 &#8212;&nbsp;&nbsp;&nbsp; 15 recursive calls in 0,0009108 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 6) =&nbsp;&nbsp;&nbsp;&nbsp; 8 &#8212;&nbsp;&nbsp;&nbsp; 25 recursive calls in 0,0015319 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 7) =&nbsp;&nbsp;&nbsp; 13 &#8212;&nbsp;&nbsp;&nbsp; 41 recursive calls in 0,0021847 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 8) =&nbsp;&nbsp;&nbsp; 21 &#8212;&nbsp;&nbsp;&nbsp; 67 recursive calls in 0,0031991 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 9) =&nbsp;&nbsp;&nbsp; 34 &#8212;&nbsp;&nbsp; 109 recursive calls in 0,0053804 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (10) =&nbsp;&nbsp;&nbsp; 55 &#8212;&nbsp;&nbsp; 177 recursive calls in 0,0096687 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (11) =&nbsp;&nbsp;&nbsp; 89 &#8212;&nbsp;&nbsp; 287 recursive calls in 0,0143352 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (12) =&nbsp;&nbsp; 144 &#8212;&nbsp;&nbsp; 465 recursive calls in 0,0238466 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (13) =&nbsp;&nbsp; 233 &#8212;&nbsp;&nbsp; 753 recursive calls in 0,0401255 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (14) =&nbsp;&nbsp; 377 &#8212;&nbsp; 1219 recursive calls in 0,0643954 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (15) =&nbsp;&nbsp; 610 &#8212;&nbsp; 1973 recursive calls in 0,1061213 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (16) =&nbsp;&nbsp; 987 &#8212;&nbsp; 3193 recursive calls in 0,1682571 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (17) =&nbsp; 1597 &#8212;&nbsp; 5167 recursive calls in 0,2774713 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (18) =&nbsp; 2584 &#8212;&nbsp; 8361 recursive calls in 0,4582997 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (19) =&nbsp; 4181 &#8212; 13529 recursive calls in 0,7425936 seconds<\/p>\n<p>&nbsp;Well, nearly 20 thousand recursions per second isn&rsquo;t too bad at all. Just one last remark. There is also an iterative solution available that is by far faster, of course, as shown here:<\/p>\n<p style=\"padding-left: 30px\">function fibonacci($n)<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; for ($i=0; $i -le $n; $i++){<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $global:calls++<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp;&nbsp;&nbsp;&nbsp; ($i -eq 0) {$n1=$n2=0}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elseif ($i -eq 1) {$n1=1}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; {$n1, $n2 = ($n1+$n2), $n1}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $n1<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\"># produce some test values<\/p>\n<p style=\"padding-left: 30px\">0..19 | %{ $calls=0; &#8220;Fibonacci ({0,2}) = {1,5} &#8212; {2,5} recursive calls in {3,-9} seconds&#8221; `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; -f $_, (fibonacci $_), $calls, (Measure-Command {fibonacci $_}).TotalSeconds}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 0) =&nbsp;&nbsp;&nbsp;&nbsp; 0 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 1 recursive calls in 0,0002074 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 1) =&nbsp;&nbsp;&nbsp;&nbsp; 1 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 2 recursive calls in 6,65E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 2) =&nbsp;&nbsp;&nbsp;&nbsp; 1 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 3 recursive calls in 8,11E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 3) =&nbsp;&nbsp;&nbsp;&nbsp; 2 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 4 recursive calls in 7,55E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 4) =&nbsp;&nbsp;&nbsp;&nbsp; 3 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 5 recursive calls in 8,21E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 5) =&nbsp;&nbsp;&nbsp;&nbsp; 5 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 6 recursive calls in 8,64E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 6) =&nbsp;&nbsp;&nbsp;&nbsp; 8 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 7 recursive calls in 9,23E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 7) =&nbsp;&nbsp;&nbsp; 13 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 8 recursive calls in 9,95E-05&nbsp; seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 8) =&nbsp;&nbsp;&nbsp; 21 &#8212;&nbsp;&nbsp;&nbsp;&nbsp; 9 recursive calls in 0,0001038 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci ( 9) =&nbsp;&nbsp;&nbsp; 34 &#8212;&nbsp;&nbsp;&nbsp; 10 recursive calls in 0,0001094 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (10) =&nbsp;&nbsp;&nbsp; 55 &#8212;&nbsp;&nbsp;&nbsp; 11 recursive calls in 0,0001156 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (11) =&nbsp;&nbsp;&nbsp; 89 &#8212;&nbsp;&nbsp;&nbsp; 12 recursive calls in 0,0001215 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (12) =&nbsp;&nbsp; 144 &#8212;&nbsp;&nbsp;&nbsp; 13 recursive calls in 0,0001303 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (13) =&nbsp;&nbsp; 233 &#8212;&nbsp;&nbsp;&nbsp; 14 recursive calls in 0,0001365 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (14) =&nbsp;&nbsp; 377 &#8212;&nbsp;&nbsp;&nbsp; 15 recursive calls in 0,0001377 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (15) =&nbsp;&nbsp; 610 &#8212;&nbsp;&nbsp;&nbsp; 16 recursive calls in 0,0001439 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (16) =&nbsp;&nbsp; 987 &#8212;&nbsp;&nbsp;&nbsp; 17 recursive calls in 0,0001498 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (17) =&nbsp; 1597 &#8212;&nbsp;&nbsp;&nbsp; 18 recursive calls in 0,0001554 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (18) =&nbsp; 2584 &#8212;&nbsp;&nbsp;&nbsp; 19 recursive calls in 0,0001433 seconds<\/p>\n<p style=\"padding-left: 30px\">Fibonacci (19) =&nbsp; 4181 &#8212;&nbsp;&nbsp;&nbsp; 20 recursive calls in 9,92E-05&nbsp; seconds<\/p>\n<p>&nbsp;A recursive SQL Server statement looks like this:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; with fibonacci (n1, n2, lvl) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select 0 n1, 0 n2, 1 lvl<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select case n1 when 0 then 1 else n1+n2 end, n1, lvl+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from fibonacci f<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where lvl &lt; 100<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select n1, lvl&nbsp; from Fibonacci<\/p>\n<p>And I can tell you that this statement runs in nearly no time, too! I don&rsquo;t know how the database evaluates this recursively defined statement but it is really fast! So we&rsquo;ll test our function <strong>Get-OracleResultDa<\/strong> using the fibonacci statement:<\/p>\n<p style=\"padding-left: 30px\">$conString=&#8221;User Id=hr;Password=hr;Data Source=localhost\/xe&#8221;<\/p>\n<p style=\"padding-left: 30px\">$sqlString=@&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; with fibonacci (n1, n2, lvl) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select 0 n1, 0 n2, 1 lvl<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select case n1 when 0 then 1 else n1+n2 end, n1, lvl+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from fibonacci f<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where lvl &lt; 20<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select n1, lvl&nbsp; from fibonacci<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">$timeRdr = Measure-Command {$dr=Get-OracleResultRdr $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">$timeDa&nbsp; = Measure-Command {$da=Get-OracleResultDa&nbsp; $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; D:\\Script\\Query_Oracle14.ps1<\/p>\n<p style=\"padding-left: 30px\">Time used by the DataReader : 0.0026543<\/p>\n<p style=\"padding-left: 30px\">Time used by the dataAdapter: 0.0016834<\/p>\n<p>And piping it to <strong>Out-GridView<\/strong> displays the correct values:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1778.newgraphic2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1778.newgraphic2.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>We have two columns of type OracleDecimal, which we can verify by assigning the result to a variable <strong>$dr<\/strong> and examining the type of the value:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $dr=Get-OracleResultRdr $conString $sqlString<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $dr[0].lvl.gettype()<\/p>\n<p style=\"padding-left: 30px\">IsPublic IsSerial Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">True&nbsp;&nbsp;&nbsp;&nbsp; True&nbsp;&nbsp;&nbsp;&nbsp; OracleDecimal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.ValueType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $dr[1].lvl.gettype()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsPublic IsSerial Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">True&nbsp;&nbsp;&nbsp;&nbsp; True&nbsp;&nbsp;&nbsp;&nbsp; OracleDecimal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.ValueType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>&nbsp;Another example can easily be obtained by querying the view &ldquo;sys.user_tables,&rdquo; which is part of the Oracle data dictionary. It is usually available to each user. Let&rsquo;s query some of the over 50 columns:<\/p>\n<p style=\"padding-left: 30px\">$sqlString=@&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select table_name, num_rows, blocks, avg_row_len, last_analyzed, compression<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; from user_tables<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; D:\\Script\\Query_Oracle15.ps1<\/p>\n<p style=\"padding-left: 30px\">Time used by the DataReader : 0.0223927<\/p>\n<p style=\"padding-left: 30px\">Time used by the dataAdapter: 0.0129836<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0842.newgraphic3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0842.newgraphic3.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>The results are looking good but maybe you expected that the order of the displayed columns should be different according to the select statement. I didn&rsquo;t mention it before, but, in fact, the columns of the previous example have been swapped too. If you need to keep the order, you can pipe the result to <strong>Select-Object<\/strong> and enumerate the fields in the right order:<\/p>\n<p>Get-OracleResultRdr $conString $sqlString | Select-Object table_name, num_rows, blocks, avg_row_len, last_analyzed, compression | Out-GridView&nbsp;<\/p>\n<p>This will rearrange the order of columns in the <strong>GridView<\/strong>:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4010.newgraphic4.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4010.newgraphic4.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>But wait! Why exactly could the order of the columns not be preserved? The loop that returns the columns read by the data reader did return them in the correct order because we did define the order by the parameter <strong>$i<\/strong> in the call to <strong>$rdr.GetOracleValue($i)<\/strong>, so it has to be right!<\/p>\n<p>But there is one flaw in the script code: Adding elements to the hashtable <strong>$result<\/strong> doesn&rsquo;t preserve the order in which they were added.<\/p>\n<p>And here is something new in Windows Powershell 3.0: We can get around this problem by defining an ordered hashtable:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result=[ordered]@{}<\/p>\n<p>Adding the [ordered] tag as part of the creation of the hashtable does do the job. So reordering the result by <strong>Select-Object<\/strong> is no longer needed.<\/p>\n<p>Examining the types returned reveals that we have the following results:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $dr[0] | Get-Member -MemberType NoteProperty | Select-Object definition<\/p>\n<p style=\"padding-left: 30px\">Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Oracle.ManagedDataAccess.Types.OracleDecimal AVG_ROW_LEN=14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Oracle.ManagedDataAccess.Types.OracleDecimal BLOCKS=5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Oracle.ManagedDataAccess.Types.OracleString COMPRESSION=DISABLED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Oracle.ManagedDataAccess.Types.OracleDate LAST_ANALYZED=08\/27\/2011 08:55:25 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Oracle.ManagedDataAccess.Types.OracleDecimal NUM_ROWS=4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Oracle.ManagedDataAccess.Types.OracleString TABLE_NAME=REGIONS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>So, we have retrieved three <strong>OracleDecimals<\/strong>, two <strong>OracleStrings<\/strong>, and one <strong>OracleDate<\/strong> here, which is quite close to what you might have guessed.&nbsp;We haven&rsquo;t done that before, but now it is time to compare the result types returned by the data adapter version and the final data reader version, too:<\/p>\n<p style=\"padding-left: 30px\">$da=Get-OracleResultDa&nbsp; $conString $sqlString<\/p>\n<p>Both <strong>$da<\/strong> and <strong>$dr<\/strong> are arrays of objects, but <strong>$dr[0]<\/strong> is a <strong>PsCustomObject<\/strong>, whereas <strong>$da[0]<\/strong> is a <strong>DataRow<\/strong> object.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $dr[0].GetType()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsPublic IsSerial Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">True&nbsp;&nbsp;&nbsp;&nbsp; False&nbsp;&nbsp;&nbsp; PSCustomObject&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Object &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Users\\Schulte&gt; $da[0].GetType()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">IsPublic IsSerial Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">True&nbsp;&nbsp;&nbsp;&nbsp; False&nbsp;&nbsp;&nbsp; DataRow&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Object&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>&nbsp;This is not too surprising, but there is an additional difference: Our columns that have been &ldquo;noteproperties&rdquo; using the data reader are &ldquo;properties&rdquo; if we use the datadapter. And even the types are not identical, though similar:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;PS C:\\Users\\Schulte&gt; $da[0] | Get-Member -MemberType Property | Select-Object -ExpandProperty definition<\/p>\n<p style=\"padding-left: 30px\">decimal AVG_ROW_LEN {get;set;}<\/p>\n<p style=\"padding-left: 30px\">decimal BLOCKS {get;set;}<\/p>\n<p style=\"padding-left: 30px\">string COMPRESSION {get;set;}<\/p>\n<p style=\"padding-left: 30px\">datetime LAST_ANALYZED {get;set;}<\/p>\n<p style=\"padding-left: 30px\">decimal NUM_ROWS {get;set;}<\/p>\n<p style=\"padding-left: 30px\">string TABLE_NAME {get;set;}<\/p>\n<p>&nbsp;If we look at the script code &hellip;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $da=New-Object Oracle.ManagedDataAccess.Client.OracleDataAdapter($cmd);<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet=New-Object System.Data.DataTable<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [void]$da.fill($resultSet)<\/p>\n<p>&nbsp;&hellip; and think about the <strong>DataTable<\/strong> used to retrieve the results from the database, it might become quite clear that we are not dealing with an Oracle specific object. <strong>System.Data.dataTable<\/strong> is a .NET object that doesn&rsquo;t know of <strong>OracleDecimals<\/strong>, <strong>OracleStrings<\/strong>, or an <strong>OracleDate<\/strong>. It just returns the corresponding .NET types.<\/p>\n<p>&nbsp;Back to our original question: Is the data adapter faster than the data reader? Yes, it looks like that. And that is an observation that is even opposite to some articles I have read before.<\/p>\n<p>We had 0,292 seconds for the data adapter, and now we still have 0,373 seconds for the data reader, which is small, but in recurring queries and maybe if larger result sets have to returned, significant difference!<\/p>\n<p>If you think: Why should I bother? I will always use the data adapter that returns a ready to use dataset or a data table with less coding in a smaller amount of time? First of all: I am not sure if it may not be possible to tune the data reader further with special database parameters like the fetchsize to make it even faster.<\/p>\n<p>Secondly, and more importantly, if you have to return a large amount of rows things may change&mdash;especially if you can&rsquo;t keep the dataset in memory anymore. The data reader can be used to serially progress each data row, the data adapter has to fetch all the data before you can progress any row.<\/p>\n<p>One other thing to remember is that you have a permanent connection to the database while you use the data reader to fetch each row. You have to manually open and close the connection before you start reading the data and after you finished to do so.<\/p>\n<p>The data adapter does this behind the scenes in its fill-method for you. It only connects to the database to populate the data set or table used to keep the results of the query.<\/p>\n<p>In fact I did check with the still available, though deprecated, version of the Microsoft implementation of the Oracle client. If you still want to use it, you may have to load the assembly if you are using the .NET 4 client profile.<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Add-type -AssemblyName System.Data.OracleClient<\/p>\n<p>Other necessary changes include replacing <strong>Oracle.ManagedDataAccess.Client <\/strong>with <strong>System.Data.OracleClient<\/strong> and using a different connection string. Instead of <strong>User Id=hr;Password=hr;Data Source=localhost\/xe<\/strong>, we have to build a slightly different connection string: <strong>$conString=&#8221;Uid=hr;Pwd=hr;Data Source=localhost\/xe<\/strong>&#8220;<\/p>\n<p>The whole script looks like that now:<\/p>\n<p style=\"padding-left: 30px\">Add-type -AssemblyName System.Data.OracleClient<\/p>\n<p style=\"padding-left: 30px\">function Get-OracleResultRdr<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bdata source\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$conString,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bselect\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet=@()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; try {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con = New-Object System.Data.OracleClient.OracleConnection($conString)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd.CommandText= $sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con.Open()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames=$rdr.GetSchemaTable() | Select-Object -ExpandProperty ColumnName<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result=[ordered]@{}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ($i=0; $i -lt $rdr.FieldCount; $i++) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 0..($rdr.FieldCount-1) | %{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result.Add($columnNames[$i], $rdr.GetOracleValue($i))<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;[pscustomobject]$result<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } catch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Error ($_.Exception.ToString())<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } finally {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($con.State -eq &#8216;Open&#8217;) { $con.close() }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">function Get-OracleResultDa<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bData Source\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$conString,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bselect\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet=@()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; try {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con = New-Object System.Data.OracleClient.OracleConnection($conString)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd.CommandText= $sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $da=New-Object System.Data.OracleClient.OracleDataAdapter($cmd);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet=New-Object System.Data.DataTable<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [void]$da.fill($resultSet)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } catch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Error ($_.Exception.ToString())<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } finally {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($con.State -eq &#8216;Open&#8217;) { $con.close() }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\"># Test data for functions<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$conString=&#8221;Uid=hr;Pwd=hr;Data Source=localhost\/XE&#8221;<\/p>\n<p style=\"padding-left: 30px\">$sqlString=@&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; with resultset (intCount, strCount, datCount) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select 1 intCount, &#8216;Number_&#8217; || to_char(1) strCount, sysdate datCount<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select r.intCount+1, &#8216;Number_&#8217; || to_char(intCount+1), sysdate+intCount+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from resultset r<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where r.intCount &lt; 10000<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select * from resultset<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">$timeRdr = Measure-Command {$dr=Get-OracleResultRdr $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">$timeDa&nbsp; = Measure-Command {$da=Get-OracleResultDa&nbsp; $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8220;Time used by the DataReader : &#8221; + $timeRdr.TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">&#8220;Time used by the dataAdapter: &#8221; + $timeDa.TotalSeconds<\/p>\n<p>After clearing the database buffer cache and the shared pool, up came the following results:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Windows\\system32&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,5704413<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Windows\\system32&gt; (Measure-Command {Get-OracleResultDa $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,2791416<\/p>\n<p>The results have been pretty much the same as those that we have seen before using the managed Oracle data provider!<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;&nbsp;Exchanging the Oracle Managed data provider with the unmanaged version doesn&rsquo;t change much either.<\/p>\n<p>&nbsp;<\/p>\n<p>Lastly, we could still revert to the something &ldquo;completely different&rdquo;: We can still use ODBC or OLE DB to query our database!<\/p>\n<p>Using the Oracle OleDb provider requires that it is registered on your local machine. Usually it should have been registered during the installation process of the ODAC if you don&rsquo;t uncheck that component, but I already have noticed that this is not always true. <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/windows\/downloads\/index-090165.html\" target=\"_blank\">Oracle offers a 64-bit version of the OleDb provider<\/a>, which is something that Microsoft doesn&rsquo;t offer.<\/p>\n<p>If you want the 32-bit version, you have to <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/windows\/downloads\/index-101290.html\" target=\"_blank\">download the ODAC package from Oracle<\/a>.<\/p>\n<p>&nbsp;If you have to register any of the two versions, pay attention of the regsvr32.exe version you are using! Let&rsquo;s say the 32-bit version of ODAC has been unzipped to d:\\oracle\\ODAC32. In this case, we&rsquo;ll open Windows Powershell (or a command prompt) with administrative privileges and set the current directory to d:\\Oracle\\Odac32\\oledb\\bin\\ and call the correct 32 bit version of regsvr32, which is C:\\Windows\\SysWOW64\\regsvr32.exe OraOLEDB11.dll<\/p>\n<p>(if your operating system has been installed to drive C).<\/p>\n<p>&nbsp;<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3581.newgraphic6.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3581.newgraphic6.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>The 64-bit version would have to be registered with C:\\Windows\\System32\\regsvr32.exe OraOLEDB11.dll, and you might have set the working directory to d:\\Oracle\\Odac64\\oledb\\bin\\ before, if you had unzipped it there.<\/p>\n<p>Now we can work with the 32- and\/or 64-bit versions of Windows Powershell without problems!&nbsp;Otherwise, we may have encountered error messages reporting that the Oracle.OleDb provider is not registered on the local machine.<\/p>\n<p>The changes to the script required to use the OleDb provider are very little: We have to replace each occurrence of the string Oracle.ManagedDataAccess.Client.Oracle with System.Data.OleDb.OleDb and use a different connection string, as shown here:<\/p>\n<p style=\"padding-left: 30px\">$conString=&#8221;Provider=OraOLEDB.Oracle;Data Source=XE;User Id=hr;Password=hr;&#8221;<\/p>\n<p>That&rsquo;s all! If we clear the Oracle cache and run the usual timings, we can see&nbsp; that using OleDb is a little bit slower that our previous solution.<\/p>\n<p style=\"padding-left: 30px\">&nbsp;PS D:\\Oracle\\Odac32\\oledb\\bin&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,9656623<\/p>\n<p style=\"padding-left: 30px\">PS D:\\Oracle\\Odac32\\oledb\\bin&gt; (Measure-Command {Get-OracleResultDa $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,3766087<\/p>\n<p>Being COM-based might be one reason for that because we have another level of indirection between the database and the client, where a lot of processing, especially type conversion may have to take place.<\/p>\n<p>If you use the Microsoft OleDb provider for Oracle, there is only one change to the connection string required: We have to use another provider name Provider=MSDAORA instead of Provider=OraOLEDB.Oracle<\/p>\n<p>The timing results are quite the same. But remember there is no 64-bit version of this provider available.<\/p>\n<p>The last standard solution we could fall back to is using the old ODBC provider. Windows has some standard ODBC drivers available that include the &ldquo;Microsoft ODBC for ORACLE&rdquo; driver &hellip; if &hellip; if you are running a 32-bit OS or at least are planning to use the 32-bit ODBC driver version. The standard procedure: Clicking on ODBC data sources in administrative tools won&rsquo;t show the Oracle driver if you are running a 64-bit OS! You might see only a few drivers like these:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8750.newgraphic7%20(2).png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8750.newgraphic7%20(2).png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>The highlighted driver is the Oracle 64-bit ODBC driver that I did install on my system before. You can <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/windows\/downloads\/index-090165.html\" target=\"_blank\">download it as part of the 64-bit ODAC<\/a>.&nbsp;The 32-bit version is, of course, <a href=\"http:\/\/www.oracle.com\/technetwork\/developer-tools\/visual-studio\/downloads\/index.html\" target=\"_blank\">part of the 32-bit ODAC download<\/a>.<\/p>\n<p>&nbsp;If you want to see the 32-bit drivers you have to close this window and execute:<\/p>\n<p style=\"padding-left: 30px\">C:\\Windows\\SysWOW64\\odbcad32.exe<\/p>\n<p>This shows a lot of more available drivers:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7180.newgraphic8%20(2).png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7180.newgraphic8%20(2).png\" alt=\"\" border=\"0\" \/><\/a>&nbsp;<\/p>\n<p>Additionally, we can find the Microsoft ODBC driver for Oracle here:<\/p>\n<p>&nbsp;<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6253.newgraphic9.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6253.newgraphic9.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>Again, there are some same small changes that have to be made to the script if you want to use the ODBC driver.&nbsp;By using the 32-bit driver, these changes include: We have to replace each occurrence of the string&nbsp;<strong>Oracle.ManagedDataAccess.Client.Oracle<\/strong> with<strong>System.Data.Odbc.Odbc<\/strong> and use a different connection string, as shown here:<\/p>\n<p style=\"padding-left: 30px\">$conString=&#8221;Driver={Oracle in ORAHOME11G_Client32};Dbq=xe;UID=hr;PWD=hr&#8221;&nbsp;<\/p>\n<p>&nbsp;Additionally, we have to change the validation of the parameter <strong>$conString<\/strong> because we did expect a &ldquo;Data Source&rdquo; component as part of the connection string.<\/p>\n<p>Here we could probably use the &ldquo;driver&rdquo; part:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bdriver\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$conString,<\/p>\n<p>&nbsp;Another subject to change is the call to <strong>$rdr.GetOracleValue($i)<\/strong>. Because there is no such function! We have to use <strong>$rdr.GetValue($i)<\/strong> instead.<\/p>\n<p>&nbsp;The resulting script is listed, as shown:<\/p>\n<p style=\"padding-left: 30px\">function Get-OracleResultRdr<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bdriver\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$conString,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;[ValidateScript({$_ -match &#8216;\\bselect\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet=@()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; try {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con = New-Object System.Data.Odbc.OdbcConnection($conString)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$cmd.CommandText= $sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con.Open()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $rdr=$cmd.ExecuteReader()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $columnNames=$rdr.GetSchemaTable() | Select-Object -ExpandProperty ColumnName<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ($rdr.Read()) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result=@{}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ($i=0; $i -lt $rdr.FieldCount; $i++) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result.Add($columnNames[$i], $rdr.GetValue($i))<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [pscustomobject]$result<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } catch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Error ($_.Exception.ToString())<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } finally {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($con.State -eq &#8216;Open&#8217;) { $con.close() }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">function Get-OracleResultDa<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bdriver\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$conString,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateScript({$_ -match &#8216;\\bselect\\b&#8217;})]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(Mandatory=$true)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string]$sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet=@()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; try {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $con = New-Object System.Data.Odbc.OdbcConnection($conString)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd=$con.CreateCommand()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $cmd.CommandText= $sqlString<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $da=New-Object System.Data.Odbc.OdbcDataAdapter($cmd);<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet=New-Object System.Data.DataTable<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [void]$da.fill($resultSet)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } catch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Error ($_.Exception.ToString())<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; } finally {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($con.State -eq &#8216;Open&#8217;) { $con.close() }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $resultSet<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\"># Test data for functions<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\"># $conString=&#8221;Driver={Microsoft ODBC for Oracle};Server=XE;UID=hr;PWD=hr&#8221;<\/p>\n<p style=\"padding-left: 30px\">$conString=&#8221;Driver={Oracle in ORAHOME11G_Client32};Dbq=xe;UID=hr;PWD=hr&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$sqlString=@&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; with resultset (intCount, strCount, datCount) as (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select 1 intCount, &#8216;Number_&#8217; || to_char(1) strCount, sysdate datCount<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dual<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union all (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select r.intCount+1, &#8216;Number_&#8217; || to_char(intCount+1), sysdate+intCount+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from resultset r<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where r.intCount &lt; 10000<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; )<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; select * from resultset<\/p>\n<p style=\"padding-left: 30px\">&#8220;@<\/p>\n<p style=\"padding-left: 30px\">$timeRdr = Measure-Command {Get-OracleResultRdr $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">$timeDa&nbsp; = Measure-Command {Get-OracleResultDa&nbsp; $conString $sqlString}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8220;Time used by the DataReader : &#8221; + $timeRdr.TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">&#8220;Time used by the dataAdapter: &#8221; + $timeDa.TotalSeconds<\/p>\n<p>Timing the data reader and data adapter reveal the following results:<\/p>\n<p style=\"padding-left: 30px\">PS D:\\Oracle\\Odac32\\oledb\\bin&gt; (Measure-Command {Get-OracleResultRdr $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">1,099397<\/p>\n<p style=\"padding-left: 30px\">PS D:\\Oracle\\Odac32\\oledb\\bin&gt; (Measure-Command {Get-OracleResultDa $conString $sqlString}).TotalSeconds<\/p>\n<p style=\"padding-left: 30px\">0,7356118<\/p>\n<p>The results are pointing into the right direction: The ODBC driver solution is the slowest way to retrieve the data.<\/p>\n<p>But, if you just retrieve 10 thousand rows with three columns you can probably use any of these technologies without having to wait significantly longer! A real life test with more data will have more significance, of course.<\/p>\n<p>We just scratched the surface as we did query some data from our Oracle database and we are done! We didn&rsquo;t update, delete, or insert any data. And we didn&rsquo;t issue DDL commands, used stored procedures, ref cursors, parallel queries, and so on.<\/p>\n<p>This might have to be explored in another article or even more.<\/p>\n<p>But, we have learned a little bit about fetching data from Oracle now by using the new managed data provider and we have seen that performance problems may not be buried in database execution time only, but in the way we try to retrieve the data and return it to our application.<\/p>\n<p>So be warned.&nbsp;<\/p>\n<p><strong>Appendix:<\/strong><\/p>\n<p>&ldquo;Access to an Oracle Database Server&rdquo; is something we may have to discuss further before we can go on. Oracle supports many &ldquo;Naming Methods&rdquo; like Easy Connect, Local Naming, Directory Naming and External Naming. If you don&rsquo;t use Easy Connect, which can only be configured for TCP\/IP environments, you may have to provide a &ldquo;Tnsnames.ora&rdquo; file which specifies the required connection data. This file contains entries like that:<\/p>\n<p>XE =<\/p>\n<p>&nbsp; (DESCRIPTION =<\/p>\n<p>&nbsp;&nbsp;&nbsp; (ADDRESS = (PROTOCOL = TCP)(HOST = MyPC.MyDomain.DE)(PORT = 1521))<\/p>\n<p>&nbsp;&nbsp;&nbsp; (CONNECT_DATA =<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (SERVER = DEDICATED)<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (SERVICE_NAME = XE)<\/p>\n<p>&nbsp;&nbsp;&nbsp; )<\/p>\n<p>&nbsp; )<\/p>\n<p>The topmost XE is the network alias defined to connect to the database.<\/p>\n<p>If you need to use this tnsnames.ora file, it has to be found by the Oracle client.<\/p>\n<p>A well-known algorithm is used to search for this file (&ldquo;Sqlnet.ora&rdquo;, &ldquo;Listener.Ora&rdquo; and other configuration files may be there too). Without all the details, it is important to know that the lookup procedure includes the path of the executable, other locations in the order specified by the PATH variable, and a path pointed to by the TNS_ADMIN environment variable.<\/p>\n<p>~Klaus<\/p>\n<p>Klaus, thank you for a comprehensive and educational blog post. I really appreciate you taking the time to research and to write this article. Join me tomorrow as I talk about using Windows PowerShell to discover to hidden WMI classes so I can inventory my HID devices. It is fun, I promise.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Guest blogger and Windows PowerShell Guru Klaus Schulte talks about using Oracle ODP.NET and Windows PowerShell to simplify data access to Oracle databases. Microsoft Scripting Guy, Ed Wilson, is here. It is early in the morning in Frankfurt, Germany, and the Scripting Wife and I just returned from Prague where we had a wonderful [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[146,56,251,390,3,45],"class_list":["post-4518","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-databases","tag-guest-blogger","tag-klaus-schulte","tag-oracle","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Guest blogger and Windows PowerShell Guru Klaus Schulte talks about using Oracle ODP.NET and Windows PowerShell to simplify data access to Oracle databases. Microsoft Scripting Guy, Ed Wilson, is here. It is early in the morning in Frankfurt, Germany, and the Scripting Wife and I just returned from Prague where we had a wonderful [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4518","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=4518"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4518\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=4518"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=4518"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=4518"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}