Sharing the information you need to get development done!
Welcome to DevAuthority.Com Sign in | Join | Help
in Search

be-#

  • In SQL Server, search ALL objects for text

    Persons familiar with TOAD for Oracle know about the fairly elaborate search function that lets you search for particular text in procedures, functions, views, column names, triggers, pretty much anything.

    There's a way to do that in SQL Server as well, though you kind of have to "do it yourself." 

    Use the query below.  Make sure that you are "in" the database that you mean to search before you run this query.

    select * from sysobjects o, syscomments c where o.id=c.id

    and c.text like '%your search text here%'

    You can also limit your search by object type.  For example:

    select * from sysobjects o, syscomments c where o.id=c.id

    and c.text like '%mysearchstring%'

    and xtype='P' --search stored procedures only

    The complete list of types is below.  For more information, see:

    http://articles.techrepublic.com.com/5100-9592_11-6142579.html

  • C: Check constraint
  • D: Default constraint
  • F: Foreign Key constraint
  • L: Log
  • P: Stored procedure
  • PK: Primary Key constraint
  • RF: Replication Filter stored procedure
  • S: System table
  • TR: Trigger
  • U: User table
  • UQ: Unique constraint
  • V: View
  • X: Extended stored procedure
  • Debug a Console Application Using the .net 2.0 IDE

    I'm sure there's more than one technique for doing this, but this works for me, so I thought I'd share it.

    Depending on how you count them, there are three or four steps to debugging a .net 2.0 console application by using the IDE:

    1. Set a breakpoint in an appropriate spot
    2. If your solution has more than one project, set your console project as the start-up
    3. Set the command-line parameters in the debugger, if any
    4. Execute the application in the IDE (of course)

    1. Set a breakpoint in an appropriate spot

    There's a few ways of doing this, all of which involve of course selecting the line you want the breakpoint on.  Breakpoints are "toggles," meaning that the same action repeated a second time will reverse the original action.

    1. Click on the line you want the breakpoint on, then press F9.  A little red ball will appear to the left of the line.  This means there is a breakpoint set here.  OR-
    2. Where that little red ball is, you can directly click with the mouse to toggle it on/off.  OR-
    3. Click on the line you want the breakpoint on, then select the menu item Debug/Toggle Breakpoint.

    2. If your solution has more than one project, set your console proejct as the start-up

    Go to Solution Explorer, which is the list of projects/files that are in the solution.  If it isn't open already, use CTRL-ALT-L to open it, or, less conveniently, the menu item View/Solution Explorer.  Locate the project that is your console application and right-click on it.  Select "Set as StartUp Project" from the pop-up menu.  The project name will now be in bold.  this indicates that it is the startup project.  The startup project is the project that the IDE executes when you press F5 to start debugging (Menu:  Debug/Start Debugging).

    3. Set the command-line parameters in the debugger, if any

    This is set on the Debug tab of your Project Properties.  To get to Project Properties, first make sure to click on the project name of your console application in the Solution Explorer to select it.  Then select the "Project/Properties..." menu item.  (Note:  The menu item will contain your project's name, so if your project name is MyConsoleApp, the menu item will be "Project/MyConsoleApp Properties...")

    Find the text box in the "Start Options" section called "Command line arguments."  Enter your default command line arguments here.  These are the command line arguments that will be fed to your console app by the IDE debugger when you start the debugging session by pressing F5.

    4. Execute the application in the IDE

    As mentioned above, press F5 to start the debugging session.  Your default command line parameters will be fed to your app, and execution will pause at your breakpoint.  After which, you can step through, examine variables, etc., as you please.

    That's all there is to it, but it's one of those things that can be frustrating to try to do if you don't know about it and/or don't know where to look to find out how to do it.

  • Using Microsoft Transact-SQL Correlated Query to Clean Up Duplicate Records

    This is something I ran across as part of my job.  The query at first seems to work by magic, but some thought into what it must be doing helped.  I share my conclusions here.  I looked up some Microsoft documentation on it, which was tantalizing and confusing at the same time, as is typical.

    Here's the Microsoft documentation:  http://www.databasejournal.com/features/mssql/article.php/3485291

    Here's the science behind the magic.

    Let's talk about this query:

    select * from credential c

    where exists (select null from credential c2

    where c.key = c2.key and c.id > c2.id

    What this query does is that given the case where a set of records have a certain key, this query will return all records from that set EXCEPT for the one with the lowest id.

    Where this is particularly powerful is in a case like this:

    delete c from credential c

    where exists (select null from credential c2

    where c.key = c2.key and c.id > c2.id

    That is, for a given set of records with a certain key, this query will DELETE all records from that set EXCEPT the one with the lowest id (presumably the oldest one).  VERY useful when cleaning up data corruption having to do with duplicate records!

    What's it doing?

    Note the where clause.  First, it ensures that the 'key' field matches.  Otherwise, the query is doing a cross-product of the credential table with itself.  It then asks the question, Is the id from table 1 greater than table 2?  If it is, it returns (deletes) that record.  Otherwise, it does not.

    Let's look at that with some data.

    Key Id
    100 10
    100 20
    100 30
    200 40
    200 50

    Below is the cross-product it does, and the answer to its question, by row:

    Key0 Id0 Key1 Id1 Id0 > Id1?
    100 10 100 10 No
    100 10 100 20 No
    100 10 100 30 No
    100 20 100 10 Yes
    100 20 100 20 No
    100 20 100 30 No
    100 30 100 10 Yes
    100 30 100 20 Yes
    100 30 100 30 No
    200 40 200 40 No
    200 40 200 50 No
    200 50 200 40 Yes
    200 50 200 50 No

    ...which means that, for the delete query, it will remove records as follows.  The Id=30 is repeated and will be "deleted" twice.

    Key Id
    100 20
    100 30
    200 50

    This leaves, of course, what we wanted, which was to have a single record for each Key, and the Id that is left over is the lowest one for each Key:

    Key Id
    100 10
    200 40

    So, not really magic after all.  And very powerful.  I don't know about you, but I love to know what is going on behind the scenes -- that's what makes the creativity and the fun possible!

  • Use .net 2.0 to get file owner

    Here is a code snippet for getting a file's owner, for example, "schoolone\ebuatois'.  'schoolone' is the domain name, 'ebuatois' is the user name.

          using System.IO;
          using System.Security.AccessControl;
          using System.Security.Principal;

            //Get file owner
            string GetFileOwner(string fileFullPath)
            {
                string fileOwner = "(unknown)";

                try
                {
                    FileInfo fileInfo = new FileInfo(fileFullPath);
                    FileSecurity fileSecurity = fileInfo.GetAccessControl();
                    IdentityReference identityReference = fileSecurity.GetOwner(typeof(NTAccount));

                    fileOwner = identityReference.Value;
                }
                catch (FileNotFoundException)
                {
                    //do nothing -- this is probably the result of the file being deleted -- a normal operation
                }

                return fileOwner;
            }

    Best Practices note:  Note, I left a do-nothing Catch block in this example to demonstrate a side point.  The code this comes from was part of a FileChangeMonitor service I wrote.  I found that in the case of a deleted file, I would get a FileNotFoundException when I tried to look up the deleted file's owner (obviously).  I debated about the best solution, and two ways of solving this occurred to me:  (1) Determine from the FileWatcher event that the file had been deleted and don't call this function, or (2) put in the above 'Catch'.  I ended up doing both.

    Strictly speaking, the right way to handle it is to do (1), and not (2).  The reason for this is two-fold:  a) This is borderline using of exceptions as part of normal operation, which is a big no-no.  To go the full way is to actually return normal data or a normal return code based on an exception occurring, and in my opinion there is ALWAYS a coding alternative to prevent the need for that.  Where this is borderline is while I'm not going that whole way of having normal data be returned based on an exception, I'm still effectively telling the function to ignore an error type, which has its own dangers.

    The second reason, (b), is that this implementation of the error-handling makes this function non-re-usable, as it dramatically restricts the number of cases in which this function can be used without sacrificing functionality.  Put another way, in almost all circumstances, you WOULD want a function that returns the Owner to return a FileNotFoundException.  It just happened that in MY case that caused a problem.

    So why did I do it?  Because this function is part of a small application and it is not part of a library where I'd expect it to be reused.  I also figured that within the context of this application, there will NEVER be a case where I'd want it to return an error in FileNotFoundException -- so it actually became an advantage to leave it in.  The advantage is that if and when I use the function elsewhere in my application, I don't have to worry about it giving me an error if it happens to be being used on a file that was just deleted.  And, it being a FileChangeMonitor service, I know for a fact it won't ever be used on a file that didn't exist in the first place.

    Best-Practice Conclusion:  There are good reasons to follow best practices -- they are "best practices" after all -- but don't be a slave to them, no rule applies in ALL cases.  Know your application, know what its needs are, and make intelligent decisions based on those needs.

  • Recursively report Exception/InnerException

    This is aimed at the novice programmer.

    When an application exception occurs, it can happen that the error causes a cascade of errors as it bubbles up to your exception handler (whether it be a custom exception handler, or the .net default exception handler).  As each exception occurs, it becomes the "current" exception that is recorded in the Exception object.  The original information is not lost, however -- a reference to it is stored in the Exception object's InnerException read-only property.

    The issue is this:  In the case of this kind of "cascading" exception, the default behavior is just to show the last error that occurred.  This exception will have ittle or nothing to do with the problem that actually occurred, and will have little or not information to aid in resolving the issue.  There is an easy way around this, using recursion.

    Below is a function that will return a string that is the aggregate of all of the error messages that occurred, so the developer can trace the problem back to the original source.

            //Recursively build exception/innerexception description string
            void BuildExceptionReport(Exception ex, StringBuilder exceptionReport)
            {
                if (ex.InnerException != null)
                    BuildExceptionReport(ex, exceptionReport);

                exceptionReport.Append(ex.Message);
                exceptionReport.Append(" :::: ");
            }

    You'd call it this way:


               try
                {
                    ...code that might fail...
                }
                catch (Exception ex)
                {
                    StringBuilder exceptionReport = new StringBuilder();
                    BuildExceptionReport(ex, exceptionReport);
                   Console.WriteLine(exceptionReport.ToString());
                }

    Play with it.  The best way to understand how it works is to play with it.  You may not like the " :::: " I use to separate the exception messages.  Use what you like -- the idea is to choose a separator that is easily recognizable so that you will be able to tell where one exception message ends and another begins.  Also, it is possible to make a slight change that will reverse the order in which the exceptions are shown.  The function as coded will report the first error that occurred, then each error it caused as the error cascaded up through the call stack.  Also, you might like more exception details such as ex.Source and ex.StackTrace.  Feel free to throw those in.

    Why Stringbuilder?  Note, I use the Stringbuilder class because it's the most efficient way to build a string of arbitrary length and with an arbitrary number of steps.  It would have been more straightforward to code it as below, but not as performant:


            //Recursively build exception/innerexception description string
            string BuildExceptionReport(Exception ex)
            {
                string returnValue = string.Empty;

                if (ex.InnerException != null)
                    BuildExceptionReport(ex);

                returnValue += string.Format("{0} :::: ", ex.Message);
                //returnValue += ex.Message +  " :::: ";  //even worse

                return returnValue;
            }

    The reason it's not as performant is due to the way that .net concatenates strings.  Put simply, when joining two strings, .net creates a brand-new third string object, copies the first one into it, and then the next one.  It does this even if your code appears to do it "in place," as in the following example:

    string a = a + b;

    .net avoids this with the StringBuilder class used in the first example.  The StringBuilder class does what you'd expect it to:  It simply appends any new string to the existing object, reather than creating/copying as in simple string concatenation.

    Best practice note:  One could argue that in any given case there aren't likely to be more than 1-4 nested exceptions, and exceptions themselves are rare, so it may be overkill to use the StringBuilder for recursive exception reporting.  That is a legitimate argument, and I would leave it to taste and the needs of your particular application to help you make the determination.

  • DeflateStream/GZipStream: Be sure to compress an entire buffer -- not one byte at a time!

    I was playing around with .net 2.0's DeflateStream, which compresses streams using the GZip algorithm.  There's two different kinds of compression streams in .net 2.0.  There's DeflateStream, which compresses files without the GZip header, which means it compresses files but can't be read by GZip.  There's also GZipStream, which includes the header, and can be read by GZip.

    But that's not what I'm here to talk about.

    While playing with it I discovered that all of my compressed files were actually bigger than their non-compressed source files.  The trick turned out to be that you shouldn't try to compress one byte at a time -- you should compress an entire byte buffer at once.  Examples follow.  I also include a decompress function because you can't have ying without yang.  I use file paths as parameters to these functions, but in an enterprise environment that stresses reuse, generally it would be better to use streams as parameters, as that's a far more generic input.

    FYI, the original file is a simple text file.  Sizes:

    • 2772 - Original size
    • 3062 - Byte-by-Byte compression - bad!
    •   143 - Buffer compression - that's more like it!

    //BAD!

    void CompressTheFileByte(string uncompressedFileFullPath, string compressedFileFullPath)
    {
        FileStream fsCompressed = new FileStream(compressedFileFullPath, FileMode.OpenOrCreate);

        using (FileStream fsSource = new FileStream(uncompressedFileFullPath, FileMode.Open))
        using (DeflateStream deflate = new DeflateStream(fsCompressed, CompressionMode.Compress))
        {
            for (int by = fsSource.ReadByte(); by != -1; by = fsSource.ReadByte())
                deflate.WriteByte((Byte)by);
        }
    }

    //GOOD!

    void CompressTheFileBuffer(string uncompressedFileFullPath, string compressedFileFullPath)
    {
        FileStream fsCompressed = new FileStream(compressedFileFullPath, FileMode.OpenOrCreate);

         using (DeflateStream deflate = new DeflateStream(fsCompressed, CompressionMode.Compress))
        {
            Byte[] theBytes = File.ReadAllBytes(uncompressedFileFullPath);
            deflate.Write(theBytes, 0, theBytes.Length);
        }
    }

    //Decompress:

    void DecompressTheFile(string compressedFileFullPath, Stream destStream)
    {
        FileStream fsCompressed = File.OpenRead(compressedFileFullPath);

        Console.WriteLine(fsCompressed.Length);

        using (DeflateStream deflate = new DeflateStream(fsCompressed, CompressionMode.Decompress))
        {
            for (int myByte = deflate.ReadByte(); myByte != -1; myByte = deflate.ReadByte())
                 destStream.WriteByte((byte)myByte);
        }

        destStream.Position = 0;
    }

  • Why use Generics in .net?

    I noticed a posting on Generics on the main page, and I thought I would add my own 2 cents. Hopefully this will help clear up what Generics are, how they are different from derived classes, and when a designer might choose to use them over derived classes.

    First, a definition: Generics are nothing more than a class template, into which the compiler will drop whatever type(s) you like (within the generic definition's constraints, of course). In other words, roughly put, instead of cutting and pasting to create several functionally identical classes whose only difference is the types they operate on, let the compiler do the "cutting and pasting" for you.

    So, when would one use generics as opposed to, say, derived classes? Here's a simple example.

    Let's say that you have separate FIFO queues, each of which handle different types.

    You could define a class that simply stores the queue items as objects. But these are not type-safe, you would need to do casting, and there's that boxing/unboxing problem for value types. Plus the overhead incurred from the compiler having to maintain virtual method pointer tables (with the caveat that I remember this from my old C++ compiler days, it's possible the .net runtime has optimized this).

    So you create derived classes from the base class that each are of the required type. So that buys you type-safety and eliminates casting, but it doesn't help you with the boxing/unboxing of value types, which would still be stored as an Object reference in the base class. Worse, if there are any other methods that need to be type-safe, which there almost certainly will be, then you have to duplicate (cut/paste/modify) each of those methods in each of your derived classes. So we're starting to get pretty far away from "code reuse."

    Generics promise full code reusability.  You write the code once, and literally drop in the types that the class will operate on when you instantiate the class.  Type-safe, fast, flexible, extensible, and fully reusable.









This Blog

Post Calendar

<April 2008>
SuMoTuWeThFrSa
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Syndication



Powered by Community Server, by Telligent Systems