SQL Cursor – Forward Only vs Fast Forward

Lets take a look at two queries using CURSORS, the first one will use the FORWARD_ONLY type cursor, and the second will use the FAST_FORWARD type cursor. These two types sound very similar, but perform quite differently.

DECLARE @firstName as NVARCHAR(50);
DECLARE @middleName as NVARCHAR(50);
DECLARE @lastName as NVARCHAR(50);
DECLARE @phone as NVARCHAR(50);
DECLARE @PeoplePhoneCursor as CURSOR;
 
SET @PeoplePhoneCursor = CURSOR FORWARD_ONLY FOR
SELECT TOP 10 FirstName, MiddleName, LastName, PhoneNumber
  FROM person.Person p
 INNER JOIN person.personphone pp on p.BusinessEntityID = pp.BusinessEntityID;
 
OPEN @PeoplePhoneCursor;
FETCH NEXT FROM @PeoplePhoneCursor INTO @firstName, @middleName, @lastName, @phone;
 WHILE @@FETCH_STATUS = 0
BEGIN
     PRINT ISNULL(@firstName, '') + ' ' +
           ISNULL(@middleName, '') + ' ' +
           ISNULL(@lastName, '')  +
           ' Phone: ' + ISNULL(@phone, '') ;
     FETCH NEXT FROM @PeoplePhoneCursor INTO @firstName, @middleName, @lastName, @phone;
END
CLOSE @PeoplePhoneCursor;
DEALLOCATE @PeoplePhoneCursor;

Now for the FAST_FORWARD CURSOR example. Notice only one line has changed, that’s the line that says “SET @PeoplePhoneCursor = CURSOR FAST_FORWARD FOR”.

DECLARE @firstName as NVARCHAR(50);
DECLARE @middleName as NVARCHAR(50);
DECLARE @lastName as NVARCHAR(50);
DECLARE @phone as NVARCHAR(50);
DECLARE @PeoplePhoneCursor as CURSOR;
 
-- HERE IS WHERE WE SET THE CURSOR TO BE FAST_FORWARD
SET @PeoplePhoneCursor = CURSOR FAST_FORWARD FOR
SELECT TOP 10 FirstName, MiddleName, LastName, PhoneNumber
  FROM person.Person p
 INNER JOIN person.personphone pp on p.BusinessEntityID = pp.BusinessEntityID;
 
OPEN @PeoplePhoneCursor;
FETCH NEXT FROM @PeoplePhoneCursor INTO @firstName, @middleName, @lastName, @phone;
 WHILE @@FETCH_STATUS = 0
BEGIN
     PRINT ISNULL(@firstName, '') + ' ' +
           ISNULL(@middleName, '') + ' ' +
           ISNULL(@lastName, '')  +
           ' Phone: ' + ISNULL(@phone, '') ;
     FETCH NEXT FROM @PeoplePhoneCursor INTO @firstName, @middleName, @lastName, @phone;
END
CLOSE @PeoplePhoneCursor;
DEALLOCATE @PeoplePhoneCursor;

The FORWARD_ONLY CURSOR takes 4 times the time as the FAST FORWARD CURSOR, and the number continues to widen as the number of times the cursor loops is executed.

FAST FORWARD CURSORS are usually the fastest option with SQL Server. There may be cases where another option may work better, but the FAST FORWARD CURSOR is a good place to start if you must use a CURSOR.

The best practice is to avoid cursor but sometime they are inevitable. The alternatives could be temp tables, while loops etc.

Case sensitive search on a case insensitive sql server

Recently I had a problem where i need to search for;

  1. Foo
  2. foo

SQL Server default behavior is to do case insensitive search. so if run a query like this;

IF OBJECT_ID('tempdb..#FooTable') IS NOT NULL DROP TABLE #FooTable
SELECT x.* 
INTO #FooTable
FROM
(
	SELECT 1 AS Id, 'Foo' AS UserName
	UNION ALL
	SELECT 2 As Id, 'foo' AS UserName
) x

I will get two records back.

To do a case sensitive search, do this;

SELECT UserName
FROM #FooTable
WHERE 1=1
AND UserName = 'foo' COLLATE SQL_Latin1_General_CP1_CS_AS

Result would be;

For join operations, let’s create another table;

--Now add a second table, say salary
IF OBJECT_ID('tempdb..#FooSalaryTable') IS NOT NULL DROP TABLE #FooSalaryTable
SELECT x.* 
INTO #FooSalaryTable
FROM
(
	SELECT 1 AS Id, 'Foo' AS FooId, 4000 AS UserSalary
	UNION ALL
	SELECT 2 As Id, 'foo' As FoodId, 6000 AS UserSalary
) x

SELECT * FROM #FooSalaryTable

This is join query;

--example with join
SELECT 
	x.UserName, y.UserSalary
FROM #FooTable x
JOIN #FooSalaryTable y on x.UserName = y.FooId COLLATE SQL_Latin1_General_CP1_CS_AS
WHERE 1=1
AND x.UserName = 'foo' COLLATE SQL_Latin1_General_CP1_CS_AS

and results;

For more info, follow these articles;

https://stackoverflow.com/questions/1831105/how-to-do-a-case-sensitive-search-in-where-clause-im-using-sql-server

https://www.mssqltips.com/sqlservertip/1032/case-sensitive-search-on-a-case-insensitive-sql-server/

https://stackoverflow.com/questions/17172175/add-column-to-temp-table-invalid-column-name-decimal

Customizing ADO

This article is for the basic process template. The hierarchy is Epic, Issue and Task. Each level in this hierarchy has a page. Keep in mind that page follows a 3 section layout, Detail, Planning and Related work.

Epic customization Click on three dots (…) on the right side in Epic.

This will show following page;

Click on New field. You will get to following page;

The frequently used fields are already listed in “Use an existing field” but if you want to create a new one, you can use “Create a field”.  More important, on the left side of navigation, pay attention to Layout section. This is where you can decide where to store this field; left, center or right.

Some standard fields that can be used in these pages are;

Risk, Effort, Business Value, Start Date, Target Date, T-shirt sizing, Story points, Activity, Original Estimate, Remaining Work, Completed Work.

Resources

https://learn.microsoft.com/en-us/azure/devops/organizations/?view=azure-devops

https://learn.microsoft.com/en-us/azure/devops/organizations/settings/work/customize-process-work-item-type?view=azure-devops#what-you-can-customize

What’s a Reverse Proxy

If you’re like me, the word “proxy” is an overloaded term. In different contexts, the word proxy means something different to different people. In this case, I’m talking about a server that’s an intermediary between the caller and the receiver of a networking call (usually HTTP or similar). Before you can understand a reverse proxy, let’s talk about forward proxies (or proxy servers, as you might be familiar with).

A proxy server is a server that takes requests and re-executes the call to the Internet (or intranet) on behalf of the original caller. This can be used for caching requests to improve speed of execution or for filtering content (as well as other reasons). In Figure 1, you can see a typical proxy server diagram.

Proxy server

A reverse proxy is very much like a proxy server, but, not too surprisingly, in reverse. Instead of intercepting calls going outside the Internet/intranet, a reverse proxy intercepts calls from the outside and forwards them to local servers. Often the proxy server is the only accessible server in this scenario. If you look at Figure 2, you can see that all calls come into the reverse proxy. Often the caller has no idea that there’s a reverse proxy.

Reverse proxy

Now that you have a general idea of what a reverse proxy is, let’s talk about the why of reverse proxies.

Do I Need a Reverse Proxy?

Many projects have no need for a reverse proxy. You should learn about them anyway, because it’s another arrow in your development quiver to use when you need it. The use-case for using a reverse proxy is fairly well defined. The reverse proxy can be used in microservice scenarios where you don’t want individual clients to know about the naming or topology of your data center.

Reverse proxies are not only helpful in those microservices projects. Here are some other reasons to use a reverse proxy:

  • Service gatekeeping
  • Load balancing
  • SSL termination
  • Security
  • URL writing

Although you might want to use a reverse proxy for all of these reasons, you don’t need all of these services. Use a reverse proxy in the way your application works. You can use reverse proxies as a product (e.g., CloudFlare) or built into your own projects.

The most obvious use-case for many of you reading this article is to use a reverse proxy to provide an API gateway for microservices. A reverse proxy can expose a server that represents a single surface area for requests. The details of how the service is implemented and where the actual service resides are made opaque to the actual clients. This is what I call service aggregation. In this case, a reverse proxy is used to accept calls from clients and then pass them off to the underlying service (or cluster of services). This allows you to change the composition of the microservice without breaking clients.

Here is the list of reverse proxies;

Traefik Labs

YARP – Yet Another Proxy – Microsoft open source

For YARP, you can read more here on code magazine

You can read more about Microservices here;

Hidden / Invisible Characters

Windows 98 had some tricks using ALT+some integer to add invisible characters. These are normally called  Control Characters.

The control characters U+0000–U+001F and U+007F come from ASCII. Additionally, U+0080–U+009F were used in conjunction with ISO 8859 character sets (among others). They are specified in ISO 6429 and often referred to as C0 and C1 control codes respectively. Most of these characters play no explicit role in Unicode text handling. The characters U+0000 , U+0009 (HT), U+000A (LF), U+000D (CR), and U+0085 (CR+LF) are commonly used in text processing as formatting characters.

This is how we can identify and remove them in a string;

string input; // this is your input string
string output = new string(input.Where(c => !char.IsControl(c)).ToArray());
Console.write(output.Trim());

For testing,

Excel can be used.

Click on the Cell where you want to add character. Click Insert -> Symbols;

Select “Basic Latin” in Subset and add empty space;

This will add a special character in selected cell before or after the value depending on the position.

Notepad++ is another alternative and can be used to add special characters in a string.

  1. Go to Edit > Character Panel to show the ASCII Insertion Panel.
  2. Put the cursor where you want to insert the character.
  3. Double-click the character (in the Character column) to insert.

For more info on NotePad++ special character handling, click here.