SQL Server – Searching for Non-Alphanumeric characters Using Like

All I can say is I have never really needed to search for a percent sign or square brackets or a caret in a query until today. GooBling (Googling and Binging) didn’t return any useful results. Of course Kim Tripp, one of the sage SQL Server gurus always recommends checking Books Online first, shame on me for not checking there first but this wasn’t entirely obvious. Check out the details here: http://msdn.microsoft.com/en-us/library/ms179859.aspx

You can specify an escape character using a very, now, obvious escape character. An escape character placed in front of a pattern matching character will force SQL Server to recognize the pattern matching character as a normal character.

For example:

SELECT * FROM table WHERE col1 LIKE ‘%|%%’ ESCAPE ‘|’

The above query will return all rows where col1 contains a percent sign.

Advertisement

Cannot fetch a row using a bookmark from OLE DB provider (Msg 7333, Level 16, State 2)

Linked Server Msg 7333

If you are getting this error and are trying to resolve it. Let me give you a little background information. A bookmark in this error is a left over from SQL Server 2005 SP1 and earlier. Bookmarks after 2005 SP1 is really a referred to as a key lookup, not to be confused with primary/foreign keys. From now on I am going to refer to bookmarks as key lookups so we are uniform and using the modern terminology.

Key lookups are objects within a query that refer to a data page (where the data is actually stored in the database) from a non-clustered index.

When SQL Server is executing DML (Insert, Update, Delete) against a linked server successfully for days, months, or even years and then fails with this error:

 Cannot fetch a row using a bookmark from OLE DB provider (Msg 7333, Level 16, State 2)

Something in the query execution plan is wrong. So far I have only run into this problem using linked servers and it probably has to do with resource management within SQL Server. Perhaps someone could elaborate on this that has more experience than I. But within the query’s execution plan, SQL Server decides to switch to a different index to run the query. The query then fails because it is using an index that is lacking information to complete the request.

Resolution

Ultimately, you have to do the following:

  1. Look at your where criteria in your query that is dependent on the linked server.
  2. Review indices on the table, that the where criteria is referring to.
  3. Is your one of your criteria covered by more than one index?

If you answered yes to number 3, there is a good chance that the behavior I am describing is actually causing your problem.

To diagnose this, disable one of the indexes  that is in question.

NOTE: Never disable the clustered index, you will prevent data access to the table.

Run the query again, and it should work, if not rebuild the disabled index to bring it back online and then disable the other index. If the query works you are in business. Talk with your database administrator, developer, or vendor of the application to come up with a good solution. But this will temporarily get your query to work.

SQL Server String PadLeft

I think this comes up a lot in day to day operations. Needing to pad the left hand side of a char/varchar field. T0 address this I made a handy dandy function that works similar to the padleft string function in .Net. There is a caveat to this code, if string length also sets the max length of string being returned. Below is the code, please test it for your application before putting it into production to make sure it has the behaviour that you need.

CREATE FUNCTION [dbo].[PadLeft](
    @StringLength INT,
@String VARCHAR(1000),
@PadChar CHAR(1)
)
RETURNS VARCHAR(1000)
AS
BEGIN
    DECLARE @Result VARCHAR(1000)
    DECLARE @PadLength INT;
    SET @PadLength = @StringLength LEN(@String)
    IF @PadLength <= 0
    BEGIN
        SET @Result =LEFT(@string,@StringLength)
    END
    ELSE
    BEGIN
        SET @Result =REPLICATE(@PadChar,@PadLength)+ @String
     END
    RETURN @Result
END

SQL Server Coalesce

Coalesce is one of those old functions that has been around for a very long time and lost some of it’s lime light. It is good for a number of things but it’s VERY important to know how it behaves.

Overview

So coalesce takes any two or more parameters and takes the first parameter which IS NOT NULL and returns that value. For example:

SELECT COALESCE(null,’  ‘, ‘value’);

This would return the second argument, ‘ ‘, not the value ‘value’. You need to be very careful with this! Sometimes programmers don’t recognize the difference between null and empty values. If that is you, I have a very good article discussing null values in SQL Server, listed below:

SQL Server Null Values ~ Into the Void (pun intended)

SQL Server CTE ~ Hooray for Common Table Expressions

What is a SQL Server CTE?

CTE stands for Common Table Expression.

A CTE is basically a subquery. So why is it special? This is why they are good:

  • Separate a subquery from the body of the main query.
  • Cleaner code – CTEs enable you to separate your logically congruent code segments.
  • Can be used for improving the execution plan of your query.
  • Can be used for recursive, hierarchical queries.

When aren’t they good? Almost never. Basically, if you don’t need a subquery don’t use a CTE. Also don’t bother using a CTE when you are performing a query with resources outside of SQL Server, there are negative performance issues in SQL Server 2005, but is fixed in SQL Server 2008. Here is everything you will need to know about CTEs.

CTE Basics

Books Online

Recursive CTE

OracleConnection ~ Connection String Nightmare

I spent quite a bit of time today debugging an oracleconnection object. It would fail everytime the connection string property was set. This is what I would recieve in the error log:

Faulting module name: KERNELBASE.dll, version: 6.1.7601.17651, time stamp: 0x4e2111c0

Exception code: 0xe0434f4d

Fault offset: 0x0000d36f

I didn’t get to far Duck Duck Go’ing (or Googling) on this so I threw the assignment into an try catch block. I got an error  “Connection string is not well formed”. Connectionstrings.com had a great section on Oracle so I copied/pasted it into my code changing the pertinent data. Same issue.

After trying several things I discovered that the connection strings for Oracle cannot have a trailing semi-colon.

Data Source=IDWorks;User Id=IDWorks;Password=idw;

Data Source=IDWorks;User Id=IDWorks;Password=idw

Hope this saved you some time!

SQL Server Error when Renaming a table – SP_RENAME – Msg 15225

So if you need to rename a table sp_rename is what you would use. You would do something like the following:

exec sp_rename ‘oldname’, ‘newname’;

Here is a gotcha, it doesn’t take into account a table name that has a dot in the name. For example a table like dbo.[employee.info] will create this error:

Msg 15225, Level 11, State 1, Procedure sp_rename, Line 332

No item by the name of ‘dbo.[employee.info]’ could be found in the current database ‘database’, given that @itemtype was input as ‘(null)’.

The parsing mechanism in the stored procedure will parse it incorrectly.

The Workaround

Use the fully qualified domain name of the table (ie. databasename.schema.tablename). I found that this will work in these cases.

Drop All Tables in a Database

So I recently had to delete all tables in a database based on schema name. Here is the solution I came up with:

DECLARE @tblName VARCHAR(200) ;

 

DECLARE tbl CURSOR

FOR

SELECT SCHEMA_NAME(schema_id) + ‘.’ + name AS tableName

FROM sys.tables

WHERE schema_id IN (SCHEMA_ID(‘admdb’), SCHEMA_ID(<Your Schema Here>), SCHEMA_ID(<Your Schema Here>)) ;

 

OPEN tbl ;

 

FETCH NEXT FROM tbl INTO @tblName ;

WHILE @@FETCH_STATUS=0

BEGIN

EXEC(‘DROP TABLE ‘ + @tblName) ;

 

FETCH NEXT FROM tbl INTO @tblName ;

END

 

CLOSE tbl ;

DEALLOCATE tbl ;

 

A couple things worth mentioning is that I set the table name to 200 character varchar. Of course this script can do some damage, please, please, please make sure you don’t need anything in any of the tables before running this!

By default, drop table does not accept a variable but if you turn it into a dynamic query (wrapping it in an execute function) works perfectly.

MS Access Error: Too few parameters. Expected x

If you are getting this error it means you are probably working. Here is the deal: this error happens when you try to access an Access Database through ODBC or OLEDB. Chances are you are trying to use Access’s standard of using double quotes (“), replace them with single quotes(‘) and you should be off and running.

If that still didn’t fix your problem the error is probably quite literal in that you forgot to add a parameter to your query or that you are missing some search criteria.

Let me know if this doesn’t work for you and I can help you get up and running.

Removing Unused Indexes

Removing Unused Indexes.

This is some thought provoking information. For those of you who add indexes to everything…