SOUNDEX function seems broken in SQL Server 2012 - sql

The following statements return different SOUNDEX values in SQL Server 2012 while they produce the same value in SQL Server 2008:
PRINT SOUNDEX('BAKHSHI') --B200
PRINT SOUNDEX('Bakhshi') --B220
Has anyone else had this issue in SQL Server 2012 and knows how to get around it?

According to https://msdn.microsoft.com/en-us/library/bb510680.aspx:
SOUNDEX function implements the following rules: If upper-case H or
upper-case W separate two consonants that have the same number in the
SOUNDEX code, the consonant to the right is ignored If a set of
side-by-side consonants have same number in the SOUNDEX code, all of
them are excluded except the first. The additional rules may cause the
values computed by the SOUNDEX function to be different than the
values computed under earlier compatibility levels. After upgrading to
compatibility level 110, you may need to rebuild the indexes, heaps,
or CHECK constraints that use the SOUNDEX function. For more
information, see SOUNDEX (Transact-SQL)
So you might want to try following Microsoft's upgrade path advice. Also, SOUNDEX is collation sensitive - are your 2012 DB collations the same as your 2008 collations?

Related

Use a checkmark as an column alias in SQL Server 2008 R2

I have a requirement to do something I believe should be simple enough, but am not finding the right answer to. How do I use a checkmark as a column alias in SQL Server 2008 R2?
I've tried using Char(251) by setting it to a value and trying to assign the value as the column alias, but no joy on that one.
I've tried using Char(251) (and I know that's more of a square root mark, but not sure of the checkmark ascii value if there is one. I believe that is a unicode value?) directly but again no joy. This should be simple, but I'm simply not finding it.
Thanks.
You cannot use expressions as identifiers in SQL Server (or any other SQL database for that matter). You can, however, use Unicode characters in identifiers, so simply copy and paste the desired character:
select 'yes' as "☑︎";
or even
select 'blah' as "😀";
Having said that, you should not be doing all that -- presentation is not the task for a database engine; it should be implemented in the client application.

What is the purpose of the Cognos SQL function/expression "ascii"?

I must translate a Cognos Impromptu 7 query to TSQL. Part of the query includes the following:
nconvert((SUBSTRING((ascii(t1.TargetDate)) from 1 for 4)))
/*
where:
t1 is a table alias
TargetDate is a BIGINT contains the value 200501
*/
Can someone explain the purpose of the function/expression "ascii"?
(FYI: SQL Server ASCII function produces ascii(200501) ==> ascii(2) ==> 50 )
Bonus: If someone can point me to an online resource that includes the ascii definition, that would be appreciated. My search bore no fruit.
The official Impromptu 7.5 administrator guide is in here:
Impromptu Administration Guide 7.5.0
All functions (including text, numeric and Date / Time functions) are documented here
However, I did not find any ascii function there.
So, the second option is creating an IQD file:
Viewing SQL generated by Impromptu
If this does not help. use SQL Server profiler to see the real SQL statement that impromptu sends:
SQL Server Profiler

Is there a need to include brackets [] when running a query in SQL Server 2008?

I have SQL Server 2008 Express Edition installed and is my first time running a SQL query. I noticed that if I select to display the top 1000 rows that the query places brackets [] around the name of the database and its respective columns.
Why are there brackets around the name of the database and columns?
Is there a need to have these and if so when?
I just posted this answer on dba.stack.
They escape names that are not "friendly" - they can be useful if your database names contain special characters (such as spaces, dots or dashes) or represent SQL keywords (such as USE or DATABASE :-)). Without the square brackets, a query like this will fail:
SELECT column FROM database.dbo.table;
However if you write the query this way, the keywords are ignored:
SELECT [column] FROM [database].dbo.[table];
When building scripts or writing solutions that generate scripts from metadata (e.g. generating a script of all tables or all indexes), I always wrap entity names in square brackets so that they will work regardless of what kind of wonky names have been implemented (I am not always doing this for systems I control). You can do this easily using QUOTENAME function, e.g.:
SELECT QUOTENAME('table'), QUOTENAME('column'), QUOTENAME('database');
Results:
[table] [column] [database]
If you search my answers here for QUOTENAME you will find that I use it in a lot of scripts where I'm helping folks automate script generation or building dynamic SQL. Without the square brackets, a lot of people would run into issues running the scripts.
Enclosing a string in square braces is tells SQL Server that it should not try to parse whatever is inside them. This allows you to do use things like SQL reserved words (select, table, return, etc.) as well as spaces in identifiers. They are only required in those cases, but they are not harmful in any case.
No there isn't, but it ensures that if you had a db, table or column named as a reserved or keyword, for example date, that it wouldn't be confused with that keyword.

REPLACE function in T-SQL 2008 is different from T-SQL 2005

I am on project of migrating databases from SQL Server 2005 to 2008.
During test I found one inconsistency. In accordance to BOL http://msdn.microsoft.com/en-us/library/ms186862(v=SQL.100).aspx (2008) and http://msdn.microsoft.com/en-us/library/ms186862(v=SQL.90).aspx (2005) returns varchar. So far both are the same. However if we pass to REPLACE function column type char then difference comes out. Look at this code
declare #test table
(
testcharstring char(25)
)
insert into #test
select 'Hello'
union
select 'World'
union
select 'Hello world '
select
'"'+testcharstring+'"' as original
,'"'+replace(testcharstring,'a','A')+'"' as afterreplace
--,'"'+replace(rtrim(testcharstring),'a','A')+'"'
from #test
Result from SQL Server 2005
original afterreplace
--------------------------- ---------------------------
"Hello " "Hello"
"Hello world " "Hello world"
"World " "World"
Result from SQL Server 2008
original afterreplace
--------------------------- ---------------------------
"Hello " "Hello "
"Hello world " "Hello world "
"World " "World "
T-SQL in SQL Server 2005 removes even legitimate trailing space, not to say that it threats char(25) as varchar(25). T-SQL in SQL Server 2008 approaches type more carefully and returns results in accordance of type which it receives for transformation
I have number places in different T-SQL objects, mostly in triggers. Main idea just to make minimal changes to keep same behaviour in SQL Server 2008
Possible ways to do it
Override built-in REPLACE function Quick search suggests that it impossible however my teammate wants to research that option
Use Rtrim() functions together with REPLACE. This will require replacement in exact places in code in multiple routines (where char columns are used)
Creating own version Replace in CLR to see that CLR allows me to keep SQL Server 2005 behaviour and then again search and replace function in exact location
I would like to ask everybody if somebody came across of this issue, how did you worked out?
Also any suggestion is also welcome, may be I just do not know what settings on server instance or database level can change behaviour.
Thank you in advance!
You have different SET ANSI_PADDING options, which can also be controlled by SET ANSI_DEFAULTS
As it stands, REPLACE behaves the same in both editions. Both (2005, 2008) say:
Returns nvarchar if one of the input arguments is of the nvarchar data type; otherwise, REPLACE returns varchar.
Edit: there are 2 Connect bugs/features
My answer above is probably wrong
http://connect.microsoft.com/SQLServer/feedback/details/259840/trailing-spaces-are-lost-when-a-char-value-is-fed-to-replace
Check DB compatible level:
http://connect.microsoft.com/SQLServer/feedback/details/126092/t-sql-replace-function-seems-to-be-broken-for-char-x-variables
And as a fix, sorry, I'd use rtrim, however is it a fix? You can't override replace, and if you plan on a clr urgent, why not wrap the replace/rtrim in a SQL udf
according to MS this is a correct behavior and SQL2005 had it wrong.
in you code you are using Replace() not only as corection function (Find a pattern and replace with another pattern) but also as Trim() function (if nothing found at least trim the incoming value)
but this is wrong when you are working with Char(). the only reason to use Char() as data type is to preserve the values data length at all cost.(IMHO) as in you need to ensure that returning Value length is ALWAYS the same regardless of actual stored character count.
this is important when you need to build some kind of structure using string concatenation
as in fixed length file for output, and do not care to bother with data length checks or conversions.
otherwise you might as well use varchar() or nvarchar()
http://msdn.microsoft.com/en-us/library/ms143359(v=sql.100).aspx
In SQL Server 2005, trailing spaces specified in the first input parameter to the REPLACE function are trimmed when the parameter is of type char. For example, in the statement SELECT '<' + REPLACE(CONVERT(char(6), 'ABC '), ' ', 'L') + '>', the value 'ABC ' is incorrectly evaluated as 'ABC'.
In SQL Server 2008, trailing spaces are always preserved. For applications that rely on the previous behavior of the function, use the RTRIM function when specifying the first input parameter for the function. For example, the following syntax will reproduce the SQL Server 2005 behavior SELECT '<' + REPLACE(RTRIM(CONVERT(char(6), 'ABC ')), ' ', 'L') + '>'.

How can i search a non case sensitive word with Sql Server XQuery?

I'm using an Xml field in my Sql Server database table. I'm trying to search a word using the XQuery contains method but it seems to search only in case sensitive mode. The lower method isn't implemented on Sql Server XQuery implementation also.
¿Is there a simple solution to this problem?
If you're using SQL Server 2005, I'm afraid you're out of luck.
If you're using SQL Server 2008, you can use the upper-case function like this :
DECLARE #x xml = N'abcDEF!#4';
SELECT #x.value('fn:upper-case(/text()[1])', 'nvarchar(10)');
Here's a link on MSDN for the upper-case syntax and a couple search examples :
http://msdn.microsoft.com/en-us/library/cc645590.aspx
First link from google points to MSDN page:
contains Function (XQuery)
In order to get case-insensitive
comparisons, the upper-case or
lower-case functions can be used.