How to check Palindrome in SQL Server - sql

To check palindrome I am using REVERSE function of SQL Server.
I wanted to check how reverse function works with this sample code:
declare #string nvarchar
set #string = 'szaaa'
SELECT REVERSE(#string)
But the output was 's' in case of 'aaazs' which I expected. How should I capture the reverse? Is there any better way to find palindrome?

In SQL Server, always use lengths with the character types:
declare #string nvarchar(255);
set #string = 'szaaa';
SELECT REVERSE(#string);
The default length varies by context. In this case, the default length is "1", so the string variable only holds one character.

To check palindrome, You can use CASE Statement
DECLARE #string NVARCHAR(255);
SET #string = 'szaaa';
SELECT CASE WHEN #string=REVERSE(#string)THEN 'Is palindrome'
ELSE 'Is not palindrome'
END

Related

Perform string comaparison ignoring the diacritics

I'm trying search in Arabic text in SQL Server and need to ignore the Arabic diacritics.
So I'm using Arabic_100_CI_AI collation. but it's not work.
For example for the below query I must get 1, but it has no result!
select 1
where (N'مُحَمَّد' Collate Arabic_100_CI_AI) = (N'محمّد' Collate Arabic_100_CI_AI)
What is the problem and how can I perform diacritics insensitive comparison in Arabic text?
It seems AI flag is NOT working for Arabic. You can build your own Unicode Normalization function.
ALTER FUNCTION [dbo].[NormalizeUnicode]
(
-- Add the parameters for the function here
#unicodeWord nvarchar(max)
)
RETURNS nvarchar(max)
AS
BEGIN
-- Declare the return variable here
DECLARE #Result nvarchar(max)
-- Add the T-SQL statements to compute the return value here
declare #l int;
declare #i int;
SET #l = len(#unicodeWord + '-') - 1
SET #i = 1;
SET #Result = '';
WHILE (#i <= #l)
BEGIN
DECLARE #c nvarchar(1);
SET #c = SUBSTRING(#unicodeWord, #i, 1);
-- 0x064B to 0x65F, 0x0670 are Combining Characters
-- You may need to perform tests for this character range
IF NOT (unicode(#c) BETWEEN 0x064B AND 0x065F or unicode(#c) = 0x0670)
SET #Result = #Result + #c;
SET #i = #i + 1;
END
-- Return the result of the function
RETURN #Result
END
Following test should work correctly,
select 1
where dbo.NormalizeUnicode(N'بِسمِ اللہِ الرَّحمٰنِ الرَّحیم') = dbo.NormalizeUnicode(N'بسم اللہ الرحمن الرحیم');
Notes:
You may experience slow performance with this solution
The character range I've used in the function is NOT thoroughly tested.
For a complete reference on Arabic Unicode Character Set, see this document http://www.unicode.org/charts/PDF/U0600.pdf
Your use of collation is correct but if you carefully see the two Arabic words in your query (highlighted bold) they are completely different even though their meaning same and hence you are not getting the result (since comparison is failing)
N'مُحَمَّد' and N'محمّد'
I am pretty sure, if you try to find out their unicode value using unicode() function; their result will be different.
If you try the below query, it will succeed
select 1
where N'مُحَمَّد' Collate Arabic_100_CI_AI like '%%'
See this post for a better explanation
Treating certain Arabic characters as identical

CAST always returns 1

I'm executing this TSQL Code:
DECLARE #myString varchar;
SET #myString = '123.0'
SELECT CAST(#myString as decimal(25,10))
But I keep getting 1.00000 as an result
Changing myString to '123' doesn't change that.
Any advise on what I'm doing wrong is appreciated.
Thanks in advance!
ALWAYS use length when using varchar() (and related types) in MySQL. The default is 1 in this context. So this fixes your problem:
DECLARE #myString varchar(255);
SET #myString = '123.0';
SELECT CAST(#myString as decimal(25,10));
You are getting 1, because your code is interpreted as
DECLARE #myString varchar(1);
SET #myString = '123.0';
SELECT CAST(#myString as decimal(25,10));
The documentation is not shy about this:
When n is not specified in a data definition or variable declaration
statement, the default length is 1. When n is not specified when using
the CAST and CONVERT functions, the default length is 30.
You are missing the varchar declareation
DECLARE #myString varchar(10);
SET #myString = '123.0'
SELECT CAST(#myString as decimal(25,10))

Extracting nvarchar value from XML in T-SQL: only one character returned

In my T-SQL procedure I'm trying to extract a string value from the XML node using the .value() method, like this:
declare #criteria xml;
set #criteria = N'<criterion id="DocName"><value>abcd</value></criterion>';
declare #val nvarchar;
set #val = #criteria.value('(criterion[#id="DocName"]/value)[1]', 'nvarchar');
select #val;
I expected to get 'abcd' as a result, but I surprisingly got just 'a'.
So, the value method returns only the 1st character of the string. Can anybody tell me, what am I doing wrong? Thanks a lot.
P.S. I'm using MS SQL Server 2012
Don't use nvarchar without size. From documentation:
When n is not specified in a data definition or variable declaration
statement, the default length is 1. When n is not specified with the
CAST function, the default length is 30.
If you don't know exact length, you always can use nvarchar(max):
declare #criteria xml;
set #criteria = N'<criterion id="DocName"><value>abcd</value></criterion>';
declare #val nvarchar(max);
set #val = #criteria.value('(criterion[#id="DocName"]/value)[1]', 'nvarchar(max)');
select #val;
sql fiddle demo

Why does SQL LEN function return '1' for a string with several characters?

Simple question - why when I print the value of the #len variable in the query below would I be getting the value 1, instead of 12 (the number of characters in the specified string)?
DECLARE #string varchar
DECLARE #index int
DECLARE #len int
DECLARE #char char(1)
SET #string = 'content loop'
SET #index = 1
SET #len= LEN(#string)
print #len
Your declaration of #string is wrong. You have no length on the varchar.
Try this:
declare #string varchar(255); -- or whatever
You just learned that the default in this situation is 1.
This is clearly specified in the documentation. As a further note, MS SQL seems to make this rather complicated:
When n is not specified in a data definition or variable declaration
statement, the default length is 1. When n is not specified when using
the CAST and CONVERT functions, the default length is 30.
The right habit is to always include the length when using varchar or nvarchar.
You need to give the variable #string an actual length. Print the variable #string and it will probably return 'C'.
Becvause varChar without a length specification is taken as varChar(1)
replace varchar with varChar(30) or varChar(max)

Sql string manipulation within stored procedure

I have a field which contains article titles. I need to create friendly or pretty url's out of the article titles.
I need help manipulating the string with SQL. This has to be done within a stored procedure or function.
The requirements:
The only characters allowed are lowercase letters and numbers (a-z and 0-9)
All spaces need to be replaced with dashes.
Thanks!
(updated) I am using Sql Server 2008
I found the answer over here. Thank you all!
How to strip all non-alphabetic characters from string in SQL Server?
CREATE Function [dbo].[create_pretty_url](#Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
While PatIndex('%[^A-za-z0-9]%', #Temp) > 0
Set #Temp = LOWER(Stuff(#Temp, PatIndex('%[^A-za-z0-9]%', #Temp), 1, ''))
Return #Temp
End
To check for lowercase letters, you can use a binary collation like Latin1_General_BIN.
This SQL Server procedure checks if a string contains only spaces, digits or lowercase letters. If so, it returns 1 and replaces spaces with underscores. Else it returns -1.
if OBJECT_ID('TestProc') is null
exec ('create procedure TestProc as select 1')
go
alter procedure TestProc(
#str varchar(256),
#result varchar(256) output)
as
begin
set #result = null
set #str = REPLACE(#str,' ','_')
if #str like '%[^0-9a-z_]%' collate Latin1_General_BIN
return -1
set #result = #str
return 1
end
go
Test data:
declare #rc int
declare #result varchar(256)
exec #rc = TestProc '11 aa', #result out
select #rc, #result
exec #rc = TestProc 'NO CAPS', #result out
select #rc, #result
exec #rc = TestProc '%#$#$', #result out
select #rc, #result
-->
1 11_aa
-1 NULL
-1 NULL
You did not state which database, or version for that matter, but lets go with:
I you were to be using Sql Server 2005, 2008, have a look at using CLR functions
Adding Regular Expressions (Regex) to SQL Server 2005