Wednesday, December 16, 2009

Backing Up Oracle, Easily

As a developer I have a need to replicate environments. As I now work regularly with Oracle, my environment-maintenance duties should include duplicating Oracle databases across various machines. But how in the world do you do that?

It's been a real eye-opener to research what's involved with Oracle administration. I've come to the conclusion that the Oracle company doesn't really bother itself with things like quickstarts. Sadly, all their documentation is written in documentation-ese. What a struggle.

A few days ago I broke down and tackled the Oracle restoration challenge. I finally restored my first Oracle database today, and I thought I'd document how to do it, for the benefit of others. Essentially, I copied files over from the old server to the new one. FYI, this is what as known as a "cold" backup and recovery because the databases are shutdown when the activity occurs.

1. First, run these commands in sqlplus or Sql Developer to find out which files need to be copied:
          select name from v$datafile; -- this provides the datafiles
          select name from v$controlfile; --this provides the control files
2. Note the redo files. They are in the same directory as the datafiles.
3. Now log into the database to be replicated as sysdba
          $>sqlplus "/ as sysdba"
4. And issue the "shutdown abort" command
5. Similarly on the new server, issue the "shutdown abort" command
5. Copy all the files referred to in items 1, 2, and 3 above from the server to be replicated to the corresponding locations on the new server
6. Back in sqlplus on the server to be replicated, issue the "restart" command
7. Do the same for the new server

Congratulations! You should be up and running on the new server by now.

Wednesday, October 28, 2009

Google, My Friend

It's astonishing to me how well Google distinguishes itself in anticipating its customers' needs. I couldn't remember the file name for the Task Manager program. I only knew that it was some abbreviation of TaskManager.

I tried doing a search on "task manager command line" or something like that receiving nothing but frustration. But then remembering Google's "Did you mean . . .?" feature. I typed "cmd tskmngr" into Google's search box. There it was.

Did you mean: cmd taskmgr

Simple. Effortless.

How Again Do You Get Data Out of a Refcursor in Sql Developer?

There appears to be no way for me to memorize how to run a stored procedure in Sql Developer that uses a refcursor. So I'm putting an example here. That way I can refer to it any time I want.


variable CV_1 REFCURSOR;
declare V_INTUSERID number;
BEGIN
V_INTUSERID := 1;
spProc1(V_INTUSERID,:CV_1);
END;
PRINT CV_1;

Wednesday, October 7, 2009

Visual Studio Shortcut for Using Directives

My current vote for top Visual Studio shortcut goes to "Shift-Alt-F10."  This little beauty will bring up the "Options to help bind the selected item" dialog which will allow you to command the UI to inject the appropriate "Using" directive at the top of a class. Trying to bring up this dialog with the mouse is tricky and time-consuming. Save those precious brain cells for something else.




"Add Reference" Dialog Delays

Today I decided to reduce the impact of an annoying problem with Visual Studio--the length of time it takes to initially bring up the "Add Reference" dialog. It can take a minute! I run into this delay constantly because I seem to almost always need to add a reference to System.Configuration to every project. My approach was to create a custom project template with the reference already included. Here are the steps I took:
  • Navigate to "C:\program files\microsoft visual studio 9.0\common7\IDE\ProjectTemplates\CSharp\Windows\1033"
  • Copied the template ConsoleApplication.zip
  • Navigate to My Documents\Visual Studio 2008\Templates\ProjectTemplates\Visual C#
  • Pasted ConsoleApplication.zip
  • Opened up the zip with "Open with > Compressed (zipped) folders" and dragged "consoleapplication.csproj" onto the desktop
  • At line 45 added
  •     <Reference Include="System.Configuration" />
  • Saved the proj file
  • Opened up the zip with Winzip (or use 7zip) and dragged in the new version of "consoleapplication.csproj"
  • Closed winzip (or 7zip)
The new project template is ready to use!

The official documentation from Microsoft is here.

Tuesday, October 6, 2009

Executing Console Commands with PowerShell

I'm just starting to master PowerShell . . and I emphasize the word "starting".  Frankly, I'm disappointed with the learning curve required. PowerShell doesn't seem to be optimized, yet, for quick learning, despite that it piggy-backs off of .NET.

Here's a tip. Don't throw away those useful scraps of "DOS" commands you've been carrying around for many years.  You can reuse them inside of PowerShell. Here's an example:

 cmd /c  <PathToCommand> arg0 arg1 argEtc

Getting Started with the 7Zip Command Line

7Zip's command line tool has umpty-um options. Many of them are very useful. But if you are looking only for a command line version of the Windows' "Send to > Compressed (zipped) Folder" command, then you can get by with merely the following:

 7z a -tzip <ZippedFileName>.zip <FolderName>

Thursday, October 1, 2009

Using C Sample Code in MSDN

Here's a simple tip for Windows C (and C++) programmers. There's a wealth of C code samples in MSDN. Unfortunately, many of those I've seen and used suffer from the same deficiency: they not unicode friendly and therefore not compatible with recent versions of Visual Studio. It's relatively easy to fix, however. Substitute the _tmain function for main and for _tmain's second parameter use "_TCHAR* argv[]" instead of "char *argv[]."

Wednesday, September 16, 2009

GOTO May Be Considered Helpful

As it turns out, at least one legitimate use exists for the notorious GOTO statement: breaking out of nested loops. Knowing from first-hand experience the problems that could be caused by "goto programming", I hadn't written a goto in 25 years. Recently, however, when trying to a write function with nested loops, it dawned on me that the most elegant solution would indeed involve a goto, at least when using C#. In fact, Microsoft's C# reference guide specifically recommends using a "goto" when exiting an inner loop, I later found out. (Maybe I ought to be reading Microsoft's online docs more often.)

In reviewing Steve McConnell's Code Complete (Second Edition), as I always do when confronting fundamental coding challenges, I was surprised to find only the vaguest of advice regarding "goto"--never say never, use your head, etc. Earlier in his book, McConnell does mention a Java-only approach. Java, which doesn't implement goto, actually has the nifty solution of named blocks, allowing you to end a break statement with the name of a block. I think this is superior than using a goto, but Java seems to be the only language with this feature.

Another author I consulted in this regard was Jeff Atwood. Atwood also describes beneficial situations for using goto, but in the only in the context of an "early return," rather than as a solution specifically for exiting nested loops. On the other hand,  I really like Atwood's description of "return" and "exit" as being merely tightly scoped goto's.

Thursday, September 10, 2009

Loading Image Resources

Here's sample code to load an image resource file, which works even if the resource file is not in the executable assembly, but in a referenced assembly.

Bitmap bmp = new Bitmap(

    System.Reflection.Assembly.GetAssembly(typeof(pick_a_class)).

    GetManifestResourceStream("Dll.Path.Image.jpg"));


pick_a_class is the name of any class in the relevant assembly.

The resource name may not be obvious. Here's code to determine the exact names of the various resources:

string[] all = System.Reflection.Assembly.GetAssembly(typeof(pick_a_class)).

    GetManifestResourceNames();

Tuesday, September 8, 2009

Manipulating Xml with C#

I'm pretty fond of the XDocument class. XDocument lets you have your way with XML without requiring convoluted syntax, especially when used in conjunction with lambda expressions. Here's an example to change the value of an attribute on nodes that were found through a search criterion.


XDocument xDoc = XDocument.Load(

    new StringReader(

        @"<Customers><Customer ID=""99"" Description=""Just another customer""></Customer></Customers>"));

xDoc.Descendants("Customer").ToList().

    ForEach

    (e =>

        {

            if (e.Attribute("ID").Value == "99")

            { e.Attribute("Description").Value = "Our best customer"; }

        }

    );



Wednesday, June 10, 2009

Hiding ASP.NET Configuration Files from VSS

All I wanted to do was to keep a few ASP.NET web site files from being versioned by Visual Sourcesafe.  Seemed like a reasonable request.  I'm talking about deployment specific configuration files with things like server names in them that are referenced in web.config using the configSource attribute.  This approach is necessary for real world scenarios, where, for instance, a production server would not know what to do with the name of a database which is located only on my dev box.  Unfortunately neither Visual Studio (current version 2008) nor VSS knows how to ignore any ASP.NET files.  

I wonder what does everyone else does? I've met few ASP.NET developers who actually know about the configSource attribute. And I suspect that the few that do probably struggle originally as I have with an occasional mishap and then turn to batch scripts like as I have done for many months now.

There must be a better way, I mumbled to myself this morning. So a-Googlin' I went. Through a quick search,  I've encountered several blog posts suggesting a hack on the vssscc file for the solution. Suppposedly you can add a line like "EXCLUDED_FILE0" = "filename" and reset the "NUMBER_OF_EXCLUDED_FILES" line. There's only one catch; it doesn't work.  There went 30 minutes down the drain.

After more extensive searching, I was able to find an awkward but workable solution, from a post on a slightly different topic, which is to set the machine specific files as "hidden" in Windows. Never used that feature of Windows before!  Never had a need to.

There you are. Easy, right.  Yeah, it's easy all right, once you know.  Hard if you don't know. I can't decide: Is it surprising that  productivity insights are about the hardest thing in software development to Google for, or is really not surprising at all?  After all, internet "knowledge" seems to be mostly the blind-leading-the-blind.

It took me months to buckle-down and hunt for a solution to this annoying problem. I'm really glad I finally got around to it. I certainly hope, however, that in the future my futility-o-meter becomes more sensitive and I don't wait as long when I run into productivity snags.

Saturday, May 30, 2009

Sorry. We Get the Support Documentation We Deserve

We programmers love to mumble to ourselves in abject silence about how poorly a commercial framework, api, server app, etc is documented. Though such complaints might be understandable, I suspect that the lack of effective documentation is many instances at least partly a function of apathy on the part of the user base.

Recently, I ran into perhaps the vauguest and cryptic Oracle error messages of all time: "ORA-01461 can bind a LONG value only for insert into a LONG column."

Huh? LONG? LONG is a defunct data type. Hey Oracle, what I really need to know is which column? And which table? And what exactly is meant by a "LONG value?" It's just a string characters.

Eventually I figured out that the offending insert statement referred to a column that was varchar2(4000 characters). But my string only had 2020 characters. So I should be good. Right?

Turns out Oracle has a built-in global limitation of 4000 bytes, not characters, for a varchar2. See http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/datatype.htm#CNCPT01. Even if you specify 4000 characters, the 4000 byte limit overrides. Depending on the encoding a character can be and usually is greater than one byte. Characters are typically 2 bytes. So my 2020-character string actually occupies 4040 bytes. Thus, my insert was over the global limit.

But why does the error message use the term LONG? The LONG data type can be up to 2 gigabytes. Evidently, this error message dates back to yesteryear when the only way to upload a character string longer than 4000 bytes to a table was to use a LONG column. Today, you can use a bunch of different LOB data types, instead of LONG.

Here's what really burns me: Googling "ORA-01461" provided no answers. Hmmm. What's up with that, my fellow Oracle programmers? Okay, so Oracle is not connecting the error message with the likely context in which you would see error message. Yes, that sucks. But what about our responsibilities? I haven't run across anyone on the interwebs complaining about how utterly lame and useless this error message is. If we don't complain with specificity and articulation, don't expect old-line software vendors such as Oracle to give a hoot.


Thursday, May 14, 2009

Variables in Sql Developer

Ever find yourself having to remember how to to use variables in Oracle's handy tool Sql Developer? Me, I can never remember. That's why this post is here.

There are two types of variables in the Oracle world: substitution variables and bind variables. It's important to remember that you can't use substitution variables in Sql Developer, but you can use bind variables. The syntax for bind variables is the following:

variable custno number
exec : custno := 99
Select * from customer where customerId = : custno;

Now I'll remember.


Thursday, April 23, 2009

.Net Code Converters

Once in a while I find a useful code sample written in VB.Net. Today I needed some code that essentially does the work of OracleCommandBuilder.DeriveParameters, but with some modifications. I found a code sample for just such a class, posted by someone named David Browne at http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-ado-net/116/Returning-Stored-Procedure-Parameters. Unfortunately, Mr. Browne's code is in VB.Net, whereas I'm in the middle of writing an app in my preferred language, C#.

The best code converter I've found thus far is from Telerik at http://converter.telerik.com. What's key about this converter is that it gives you very helpful translation error reporting for the inevitable copy-and-paste glitches that accompany any sizeable snippet gleaned from the web, such as inappropriate link breaks.

Saturday, January 3, 2009

Edit and Continue vs. Lambda Expressions

Microsoft giveth and Microsoft taketh away. One of the amazing gifts of .Net 3.5 is lambda expressions. Once you start using them, it's hard to stop. Unfortunately, lambda expressions are not compatible with another innovation: Visual Studio's Edit and Continue (or EnC). If you try to edit code with lambda expression while debugging in VS you get the following:

"Modifying a 'method' which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled."

According to this post, EnC is also incompatible with anonymous methods, a limitation present since .Net 2.