Monday, September 15, 2014

To be brief. What to do when PATH variable is too long to be real PATH.

Sometimes after installing pretty useful addins when starting SSMS you can see error message like "Exception has been thrown by the target of an invocation"

That can mean that your PATH variable is tooooo long to fit some system functions - and SSMS crashes.
Question "Why one function allows to write value that other function cannot read?" falls far beyond this topic.
So - what can you do?

First that came into my mind is manually change PATH variable - remove entries that are no longer needed and replace full folder names with the same names but in 8.3 format.
But stop! My PATH variable is more than 2K chars long! I dont want to make all these changes by my own hands!
Lets write small  program instead, ok?

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace ShortenPath
{
    class ShortifyPath
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern int GetShortPathName(String pathName, StringBuilder shortName, int cbShortName);
        static void Main(string[] args)
        {
            string path = Environment.GetEnvironmentVariable("PATH");
            Console.WriteLine("Current path value:{0}",path);
            string[] chunks = path.Split(new char[] {';'},StringSplitOptions.RemoveEmptyEntries);
            StringBuilder sb = new StringBuilder();
            foreach (string chunk in chunks)
            {
                StringBuilder sb1 = new StringBuilder(500);
                int n = GetShortPathName(chunk, sb1, 500);
                if (0 == n)
                {
                    if (2 != Marshal.GetLastWin32Error())
                    {
                        Console.WriteLine("Something went wrong...");
                        Console.WriteLine("{0}", Marshal.GetLastWin32Error().ToString());
                        return;
                    }
                    else
                    {
                        sb1.Append(chunk);
                    }
                }
                sb.AppendFormat("{0};", sb1.ToString());
            }
            Console.WriteLine("Path is shortened! Old len: {0}, new len {1}",path.Length,sb.ToString().Length);
            Console.WriteLine(sb.ToString());
        }
    }
}

Compile it using csc.exe
C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe ShortenPath.cs

And voila!
Run it and the program will print old value of PATH variable and the new value with shortened folder names. If you agree with result then you can use new value as value for PATH variable.
In my case I've saved about 500 chars from 2000.

Monday, August 18, 2014

SQL Code Guard v2.6 released

Today we released new version of SQL Code Guard, 2.6
Main changes:
1. Bug fixing
2. Small GUI and usability improvements
3. Fixed support of SQL2014
4. Changed behavior of some issues.

Enjoy!

Monday, August 4, 2014

ExpressProfiler - new release

Just released new build of ExpressProfiler.
No major changes, just cosmetic improvements - shortcut here, confirmation dialog there, new captured events (SQL:StmtStarting/Completed, Blocked Process report), descriptions for events/columns.
Still digitally signed, still 2 options - installation package (including Red Gate Ecosystem registration ) and standalone application.

Also do not forget to try our main t-sql tool - Sql Code Guard. It is really cool :)

Tuesday, July 22, 2014

Keep it simple.... you know.

Twice a week I am asked "why don't you add new cool feature to ExpressProfiler?"
The answer is as simple as ExpressProfiler itself - you should always keep things as simple as you can.

Should be balance.
On one hand you have nothing that requires nothing and does nothing - perfect minimalism.
On the other hand you have standard SQL Profiler - it does all and requires all.

Express Profiler should be as simple as possible, so you could easily copy and use it; and as useful as possible so you would be able and wanted to use it.

And yes - sometimes I simply too lazy to implement feature request.


Monday, July 7, 2014

[BP017] DELETE statement without WHERE clause


Sometimes people ask me: "What wrong with following code? Why issue BP017 is registered?"
delete d
from    dbo.Data d inner join #ids i on d.id = i.id

As you can see, rows to be deleted are limited by joining with temporary table named #ids which apparently contains a list of needed row identifiers.
So what is the problem? Why BP017 is registered?

Monday, June 30, 2014

I like to move it, move it. Upload and download binary data to or from SQL Server using standard tools

Imagine that you have a huge collection of Hello Kitty images (I do).
One day you make a decision to organize your collection - sort it, label it, tag it, remove duplicates and so on. The first thing you need - sophisticated data storage, of course. And it is obvious that you choose SQL Server - the world's best database platform :)
And since SQL Server is already present in our Universe - how about to load binary data into it?

Monday, June 23, 2014

ExpressProfiler: Yet another "when and why" story.

Core of ExpressProfiler  was born about 8 years ago when I worked for a company whose mission was the migration of Oracle and Sybase to SQL Server. We used a tool for automated database code conversion and migration (a pretty good tool btw - SSMA).
If you already know what is the difference between an "automatic" and an "automated" conversion then you may guess that there were a lot of manual work involved on the rewriting and optimization of converted code.