Showing posts with label max. Show all posts
Showing posts with label max. Show all posts

Sunday, March 25, 2012

comparing nvarchar(max) column using like to non-ASCII range

Our database defines the long_value column as nvarchar(max). I want to find out which rows actually contain non-ASCII characters in that column, but this clause also returns rows with only ASCII characters:

where long_value like (N'%[' + nchar(128) + N'-' + nchar(65535) + N']%')

What am I doing wrong?

It seems to be the fact that nchar(65535) has no length. I couldn't find any really good reference to cover this (perhaps this thread: http://groups.google.com/group/comp.lang.javascript/tree/browse_frm/month/2004-09/7d3603a75c1550f3?rnum=91&_done=%2Fgroup%2Fcomp.lang.javascript%2Fbrowse_frm%2Fmonth%2F2004-09%3F), but if you run these statements:

select N'%[' + nchar(128) + N'-' + nchar(65535) + N']%'

select N'%[' + nchar(128) + N'-' + nchar(65534) + N']%'

You will see that there is no second character after the - in the second string. This should do what you want:

declare @.long_value nvarchar(max)
set @.long_value = N'abcdefghijklmnopqrstuvwxyz' + nchar(129)
select case when @.long_value like (N'%[' + nchar(128) + N'-' + nchar(65534) + N']%') then 'yes' else 'no' end

and you could add a check for the nchar(65535) also...

|||

Louis Davidson wrote:

It seems to be the fact that nchar(65535) has no length. I couldn't find any really good reference to cover this (perhaps this thread: http://groups.google.com/group/comp.lang.javascript/tree/browse_frm/month/2004-09/7d3603a75c1550f3?rnum=91&_done=%2Fgroup%2Fcomp.lang.javascript%2Fbrowse_frm%2Fmonth%2F2004-09%3F), but if you run these statements:

select N'%[' + nchar(128) + N'-' + nchar(65535) + N']%'

select N'%[' + nchar(128) + N'-' + nchar(65534) + N']%'

You will see that there is no second character after the - in the second string.

I can't corroborate your results. I'm runing SQL Server 2005, both an unpatched Enterprise Edition and the SP1 + build 2153 hotfix Developer Edition. Connected to either server's master database, the result of both queries is displayed in Management Studio with an empty box on either side of the dash. Furthermore, the results of the following queries are 1, 2, 3, and 7 as expected:

select len(nchar(65535));

select len(nchar(128) + nchar(65535));

select len(nchar(128) + N'-' + nchar(65535));

select len(N'%[' + nchar(128) + N'-' + nchar(65535) + N']%');

Louis Davidson wrote:

This should do what you want:

declare @.long_value nvarchar(max)
set @.long_value = N'abcdefghijklmnopqrstuvwxyz' + nchar(129)
select case when @.long_value like (N'%[' + nchar(128) + N'-' + nchar(65534) + N']%') then 'yes' else 'no' end

and you could add a check for the nchar(65535) also...

Well, the obvious way to add a check for nchar(65535) is to include it in the range:

N'%[' + nchar(128) + N'-' + nchar(65534) + nchar(65535) + N']%'

Which, if it worked, would indicate a bug in character range matching. But it fails in the same way as the original.

Here is a diagnostic query that suggests to me that the problem has something to do with collations (a topic I had been blissfully ignorant of). If the server's default collation or the database's collation is Latin1_General_BIN2, it returns the expected result; but if the collation is SQL_Latin1_General_CP1_CI_AS, it returns 21,230 Unicode characters between 0 and 65535 inclusive which are equal to nchar(65535). Most disturbing is the fact that 0 (NULL) and 32 (SPACE) are among them, which might explain my original problem with the character range. Try this out on different servers and databases:

declare @.code as integer

set @.code = 0

while (@.code < 65536)

begin

if (nchar(@.code) = nchar(65535))

print cast(@.code as nchar) + ' equal'

set @.code = @.code + 1

end

|||

Kevin Rodgers wrote:

Here is a diagnostic query that suggests to me that the problem has something to do with collations (a topic I had been blissfully ignorant of). If the server's default collation or the database's collation is Latin1_General_BIN2, it returns the expected result; but if the collation is SQL_Latin1_General_CP1_CI_AS, it returns 21,230 Unicode characters between 0 and 65535 inclusive which are equal to nchar(65535). Most disturbing is the fact that 0 (NULL) and 32 (SPACE) are among them, which might explain my original problem with the character range. Try this out on different servers and databases:

declare @.code as integer

set @.code = 0

while (@.code < 65536)

begin

if (nchar(@.code) = nchar(65535))

print cast(@.code as nchar) + ' equal'

set @.code = @.code + 1

end

Collations are definitely the issue, since the orginal query works as intended (returning all long_value columns with non-ASCII characters) when reformulated with an explicit collation: select * from Item_Detail

where (long_value collate Latin1_General_BIN2) like (N'%[' + nchar(128) + N'-' + nchar(65535) + N']%')

|||

Kevin Rodgers wrote:

Kevin Rodgers wrote:

Here is a diagnostic query that suggests to me that the problem has something to do with collations (a topic I had been blissfully ignorant of). If the server's default collation or the database's collation is Latin1_General_BIN2, it returns the expected result; but if the collation is SQL_Latin1_General_CP1_CI_AS, it returns 21,230 Unicode characters between 0 and 65535 inclusive which are equal to nchar(65535). Most disturbing is the fact that 0 (NULL) and 32 (SPACE) are among them, which might explain my original problem with the character range. Try this out on different servers and databases:

declare @.code as integer

set @.code = 0

while (@.code < 65536)

begin

if (nchar(@.code) = nchar(65535))

print cast(@.code as nchar) + ' equal'

set @.code = @.code + 1

end

Collations are definitely the issue, since the orginal query works as intended (returning all long_value columns with non-ASCII characters) when reformulated with an explicit collation: select * from Item_Detail

where (long_value collate Latin1_General_BIN2) like (N'%[' + nchar(128) + N'-' + nchar(65535) + N']%')

Unfortunately, the Latin1_General_CI_AS collation does not work like the Latin1_General_BIN2 collation. Can someone explain that?

comparing nvarchar(max) column using like to non-ASCII range

Our database defines the long_value column as nvarchar(max). I want to find out which rows actually contain non-ASCII characters in that column, but this clause also returns rows with only ASCII characters:

where long_value like (N'%[' + nchar(128) + N'-' + nchar(65535) + N']%')

What am I doing wrong?

It seems to be the fact that nchar(65535) has no length. I couldn't find any really good reference to cover this (perhaps this thread: http://groups.google.com/group/comp.lang.javascript/tree/browse_frm/month/2004-09/7d3603a75c1550f3?rnum=91&_done=%2Fgroup%2Fcomp.lang.javascript%2Fbrowse_frm%2Fmonth%2F2004-09%3F), but if you run these statements:

select N'%[' + nchar(128) + N'-' + nchar(65535) + N']%'

select N'%[' + nchar(128) + N'-' + nchar(65534) + N']%'

You will see that there is no second character after the - in the second string. This should do what you want:

declare @.long_value nvarchar(max)
set @.long_value = N'abcdefghijklmnopqrstuvwxyz' + nchar(129)
select case when @.long_value like (N'%[' + nchar(128) + N'-' + nchar(65534) + N']%') then 'yes' else 'no' end

and you could add a check for the nchar(65535) also...

|||

Louis Davidson wrote:

It seems to be the fact that nchar(65535) has no length. I couldn't find any really good reference to cover this (perhaps this thread: http://groups.google.com/group/comp.lang.javascript/tree/browse_frm/month/2004-09/7d3603a75c1550f3?rnum=91&_done=%2Fgroup%2Fcomp.lang.javascript%2Fbrowse_frm%2Fmonth%2F2004-09%3F), but if you run these statements:

select N'%[' + nchar(128) + N'-' + nchar(65535) + N']%'

select N'%[' + nchar(128) + N'-' + nchar(65534) + N']%'

You will see that there is no second character after the - in the second string.

I can't corroborate your results. I'm runing SQL Server 2005, both an unpatched Enterprise Edition and the SP1 + build 2153 hotfix Developer Edition. Connected to either server's master database, the result of both queries is displayed in Management Studio with an empty box on either side of the dash. Furthermore, the results of the following queries are 1, 2, 3, and 7 as expected:

selectlen(nchar(65535));

selectlen(nchar(128)+nchar(65535));

selectlen(nchar(128)+ N'-'+nchar(65535));

selectlen(N'%['+nchar(128)+ N'-'+nchar(65535)+ N']%');

Louis Davidson wrote:

This should do what you want:

declare @.long_value nvarchar(max)
set @.long_value = N'abcdefghijklmnopqrstuvwxyz' + nchar(129)
select case when @.long_value like (N'%[' + nchar(128) + N'-' + nchar(65534) + N']%') then 'yes' else 'no' end

and you could add a check for the nchar(65535) also...

Well, the obvious way to add a check for nchar(65535) is to include it in the range:

N'%['+nchar(128)+ N'-'+nchar(65534)+nchar(65535)+ N']%'

Which, if it worked, would indicate a bug in character range matching. But it fails in the same way as the original.

Here is a diagnostic query that suggests to me that the problem has something to do with collations (a topic I had been blissfully ignorant of). If the server's default collation or the database's collation is Latin1_General_BIN2, it returns the expected result; but if the collation is SQL_Latin1_General_CP1_CI_AS, it returns 21,230 Unicode characters between 0 and 65535 inclusive which are equal to nchar(65535). Most disturbing is the fact that 0 (NULL) and 32 (SPACE) are among them, which might explain my original problem with the character range. Try this out on different servers and databases:

declare @.code as integer

set @.code = 0

while(@.code < 65536)

begin

if(nchar(@.code)=nchar(65535))

printcast(@.code asnchar)+' equal'

set @.code = @.code + 1

end

|||

Kevin Rodgers wrote:

Here is a diagnostic query that suggests to me that the problem has something to do with collations (a topic I had been blissfully ignorant of). If the server's default collation or the database's collation is Latin1_General_BIN2, it returns the expected result; but if the collation is SQL_Latin1_General_CP1_CI_AS, it returns 21,230 Unicode characters between 0 and 65535 inclusive which are equal to nchar(65535). Most disturbing is the fact that 0 (NULL) and 32 (SPACE) are among them, which might explain my original problem with the character range. Try this out on different servers and databases:

declare @.code as integer set @.code = 0 while (@.code < 65536) begin if (nchar(@.code) = nchar(65535)) print cast(@.code as nchar) + ' equal' set @.code = @.code + 1 end

Collations are definitely the issue, since the orginal query works as intended (returning all long_value columns with non-ASCII characters) when reformulated with an explicit collation: select * from Item_Detail where (long_value collate Latin1_General_BIN2) like (N'%[' + nchar(128) + N'-' + nchar(65535) + N']%')|||

Kevin Rodgers wrote:

Kevin Rodgers wrote:

Here is a diagnostic query that suggests to me that the problem has something to do with collations (a topic I had been blissfully ignorant of). If the server's default collation or the database's collation is Latin1_General_BIN2, it returns the expected result; but if the collation is SQL_Latin1_General_CP1_CI_AS, it returns 21,230 Unicode characters between 0 and 65535 inclusive which are equal to nchar(65535). Most disturbing is the fact that 0 (NULL) and 32 (SPACE) are among them, which might explain my original problem with the character range. Try this out on different servers and databases:

declare @.code as integer set @.code = 0 while (@.code < 65536) begin if (nchar(@.code) = nchar(65535)) print cast(@.code as nchar) + ' equal' set @.code = @.code + 1 end

Collations are definitely the issue, since the orginal query works as intended (returning all long_value columns with non-ASCII characters) when reformulated with an explicit collation: select * from Item_Detail where (long_value collate Latin1_General_BIN2) like (N'%[' + nchar(128) + N'-' + nchar(65535) + N']%')

Unfortunately, the Latin1_General_CI_AS collation does not work like the Latin1_General_BIN2 collation. Can someone explain that?

Sunday, March 11, 2012

Compare Dates Fields

Hello,
I have a table that has 3 date fields. I need to compare the 3 against each
other and get the max date. What would be the best way to do this,
function, case statement in a stored procedure? If there is any code
available, I would greatly appreciate it.
Thanks in advance,
sck10
Example of Table
Date1: '10/1/2006'
Date2: '11/20/2006'
Date3: '5/1/2005'
Value = '11/20/2006'
select MAX(date_column_name) from your_table_name
"sck10" <sck10@.online.nospam> wrote in message
news:%23Ta80EIPGHA.2176@.TK2MSFTNGP10.phx.gbl...
> Hello,
> I have a table that has 3 date fields. I need to compare the 3 against
> each
> other and get the max date. What would be the best way to do this,
> function, case statement in a stored procedure? If there is any code
> available, I would greatly appreciate it.
> --
> Thanks in advance,
> sck10
> Example of Table
> --
> Date1: '10/1/2006'
> Date2: '11/20/2006'
> Date3: '5/1/2005'
> Value = '11/20/2006'
>
|||Thanks, but I'm trying to figure out the latest date of 3 datefields across
the row. So the table structure would be like the following:
tblDateTracking
ScanID
UserName
SystemDate
ScanDate
IntlDate
Thanks in advance,
sck10
"ME" <ME@.mail.com> wrote in message
news:OcjoZ7IPGHA.3576@.TK2MSFTNGP15.phx.gbl...
> select MAX(date_column_name) from your_table_name
>
> "sck10" <sck10@.online.nospam> wrote in message
> news:%23Ta80EIPGHA.2176@.TK2MSFTNGP10.phx.gbl...
>
|||On Tue, 28 Feb 2006 10:08:23 -0600, sck10 wrote:

>Hello,
>I have a table that has 3 date fields. I need to compare the 3 against each
>other and get the max date. What would be the best way to do this,
>function, case statement in a stored procedure? If there is any code
>available, I would greatly appreciate it.
Hi sck10,
The fact that you need to do this suggests that your dedsign may not be
optimal. You might want to consider using a design where these three
date values in three columns in one row are transformed into the same
three date values in one column in three rows. If you do, you can use
the code posted by ME to find the maximum date.
With the current design, you're stuck with using something ugly and
unwieldy such as
SELECT ID,
CASE WHEN Date1 > Date2 AND Date1 > Date3 THEN Date1
WHEN Date2 > Date3 THEN Date2
ELSE Date3
END
FROM YourTable
or using a kludge such as
SELECT ID, MAX(TheDate)
FROM (SELECT ID, Date1 AS TheDate
UNION ALL
SELECT ID, Date2 AS TheDate
UNION ALL
SELECT ID, Date3 AS TheDate) AS Der
GROUP BY ID
Hugo Kornelis, SQL Server MVP

Compare Dates Fields

Hello,
I have a table that has 3 date fields. I need to compare the 3 against each
other and get the max date. What would be the best way to do this,
function, case statement in a stored procedure? If there is any code
available, I would greatly appreciate it.
--
Thanks in advance,
sck10
Example of Table
--
Date1: '10/1/2006'
Date2: '11/20/2006'
Date3: '5/1/2005'
Value = '11/20/2006'select MAX(date_column_name) from your_table_name
"sck10" <sck10@.online.nospam> wrote in message
news:%23Ta80EIPGHA.2176@.TK2MSFTNGP10.phx.gbl...
> Hello,
> I have a table that has 3 date fields. I need to compare the 3 against
> each
> other and get the max date. What would be the best way to do this,
> function, case statement in a stored procedure? If there is any code
> available, I would greatly appreciate it.
> --
> Thanks in advance,
> sck10
> Example of Table
> --
> Date1: '10/1/2006'
> Date2: '11/20/2006'
> Date3: '5/1/2005'
> Value = '11/20/2006'
>|||Thanks, but I'm trying to figure out the latest date of 3 datefields across
the row. So the table structure would be like the following:
tblDateTracking
--
ScanID
UserName
SystemDate
ScanDate
IntlDate
--
Thanks in advance,
sck10
"ME" <ME@.mail.com> wrote in message
news:OcjoZ7IPGHA.3576@.TK2MSFTNGP15.phx.gbl...
> select MAX(date_column_name) from your_table_name
>
> "sck10" <sck10@.online.nospam> wrote in message
> news:%23Ta80EIPGHA.2176@.TK2MSFTNGP10.phx.gbl...
> > Hello,
> >
> > I have a table that has 3 date fields. I need to compare the 3 against
> > each
> > other and get the max date. What would be the best way to do this,
> > function, case statement in a stored procedure? If there is any code
> > available, I would greatly appreciate it.
> > --
> > Thanks in advance,
> >
> > sck10
> >
> > Example of Table
> > --
> > Date1: '10/1/2006'
> > Date2: '11/20/2006'
> > Date3: '5/1/2005'
> >
> > Value = '11/20/2006'
> >
> >
>|||On Tue, 28 Feb 2006 10:08:23 -0600, sck10 wrote:
>Hello,
>I have a table that has 3 date fields. I need to compare the 3 against each
>other and get the max date. What would be the best way to do this,
>function, case statement in a stored procedure? If there is any code
>available, I would greatly appreciate it.
Hi sck10,
The fact that you need to do this suggests that your dedsign may not be
optimal. You might want to consider using a design where these three
date values in three columns in one row are transformed into the same
three date values in one column in three rows. If you do, you can use
the code posted by ME to find the maximum date.
With the current design, you're stuck with using something ugly and
unwieldy such as
SELECT ID,
CASE WHEN Date1 > Date2 AND Date1 > Date3 THEN Date1
WHEN Date2 > Date3 THEN Date2
ELSE Date3
END
FROM YourTable
or using a kludge such as
SELECT ID, MAX(TheDate)
FROM (SELECT ID, Date1 AS TheDate
UNION ALL
SELECT ID, Date2 AS TheDate
UNION ALL
SELECT ID, Date3 AS TheDate) AS Der
GROUP BY ID
--
Hugo Kornelis, SQL Server MVP

Compare Dates Fields

Hello,
I have a table that has 3 date fields. I need to compare the 3 against each
other and get the max date. What would be the best way to do this,
function, case statement in a stored procedure? If there is any code
available, I would greatly appreciate it.
--
Thanks in advance,
sck10
Example of Table
--
Date1: '10/1/2006'
Date2: '11/20/2006'
Date3: '5/1/2005'
Value = '11/20/2006'select MAX(date_column_name) from your_table_name
"sck10" <sck10@.online.nospam> wrote in message
news:%23Ta80EIPGHA.2176@.TK2MSFTNGP10.phx.gbl...
> Hello,
> I have a table that has 3 date fields. I need to compare the 3 against
> each
> other and get the max date. What would be the best way to do this,
> function, case statement in a stored procedure? If there is any code
> available, I would greatly appreciate it.
> --
> Thanks in advance,
> sck10
> Example of Table
> --
> Date1: '10/1/2006'
> Date2: '11/20/2006'
> Date3: '5/1/2005'
> Value = '11/20/2006'
>|||Thanks, but I'm trying to figure out the latest date of 3 datefields across
the row. So the table structure would be like the following:
tblDateTracking
--
ScanID
UserName
SystemDate
ScanDate
IntlDate
--
Thanks in advance,
sck10
"ME" <ME@.mail.com> wrote in message
news:OcjoZ7IPGHA.3576@.TK2MSFTNGP15.phx.gbl...
> select MAX(date_column_name) from your_table_name
>
> "sck10" <sck10@.online.nospam> wrote in message
> news:%23Ta80EIPGHA.2176@.TK2MSFTNGP10.phx.gbl...
>|||On Tue, 28 Feb 2006 10:08:23 -0600, sck10 wrote:

>Hello,
>I have a table that has 3 date fields. I need to compare the 3 against eac
h
>other and get the max date. What would be the best way to do this,
>function, case statement in a stored procedure? If there is any code
>available, I would greatly appreciate it.
Hi sck10,
The fact that you need to do this suggests that your dedsign may not be
optimal. You might want to consider using a design where these three
date values in three columns in one row are transformed into the same
three date values in one column in three rows. If you do, you can use
the code posted by ME to find the maximum date.
With the current design, you're stuck with using something ugly and
unwieldy such as
SELECT ID,
CASE WHEN Date1 > Date2 AND Date1 > Date3 THEN Date1
WHEN Date2 > Date3 THEN Date2
ELSE Date3
END
FROM YourTable
or using a kludge such as
SELECT ID, MAX(TheDate)
FROM (SELECT ID, Date1 AS TheDate
UNION ALL
SELECT ID, Date2 AS TheDate
UNION ALL
SELECT ID, Date3 AS TheDate) AS Der
GROUP BY ID
Hugo Kornelis, SQL Server MVP