EDITED after reading the MSDN forum link from the comment, very interesting.
Regardless of isolation level, two users cannot update a single page simultaneously, nor can any user read a partially updated page. Just imagine how SQL Server would deal with a page where the header says Col3 starts at byte 17. But it really starts at byte 25, because that part of the row hasn't been updated yet. There's no way a database could handle that.
But for rows larger than 8k, multiple pages are used, and that makes a half-updated column possible. Copied from the MSDN link (in case the link breaks), start this query in one window:
if object_id('TestTable') is not null
drop table TestTable
create table TestTable (txt nvarchar(max) not null)
go
insert into TestTable select replicate(convert(varchar(max),
char(65+abs(checksum(newid()))%26)),100000)
go 10
update TestTable set txt=replicate(convert(varchar(max),
char(65+abs(checksum(newid()))%26)),100000)
go 100000
This creates a table and then updates it with a string of 100.000x the same character. While the first query is running, start this query in another window:
while 1=1 begin
if exists (select * from TestTable (nolock) where left(Txt,1) <> right(Txt,1))
break
end
The second query stops when it reads a column that is half updated. That is, when the first character is different from the last. It will finish quickly, proving that it is possible to read half-updated columns. If you remove the nolock
hint, the second query will never finish.
Surprising result! A half-updated XML column might break a (nolock)
report, because the XML would be malformed.
[0-9]
is not some type of regular expression defined to just match digits.
Any range in a LIKE
pattern matches characters between the start and end character according to collation sort order.
SELECT CodePoint,
Symbol,
RANK() OVER (ORDER BY Symbol COLLATE Latin1_General_CI_AS) AS Rnk
FROM #CodePage
WHERE Symbol LIKE '[0-9]' COLLATE Latin1_General_CI_AS
ORDER BY Symbol COLLATE Latin1_General_CI_AS
Returns
CodePoint Symbol Rnk
-------------------- ------ --------------------
48 0 1
188 ¼ 2
189 ½ 3
190 ¾ 4
185 ¹ 5
49 1 5
50 2 7
178 ² 7
179 ³ 9
51 3 9
52 4 11
53 5 12
54 6 13
55 7 14
56 8 15
57 9 16
So you get these results because under your default collation these characters sort after 0
but before 9
.
It looks as though the collation is defined to actually sort them in mathematical order with the fractions in the correct order between 0
and 1
.
You could also use a set rather than a range. To avoid 2
matching ²
you would need a CS
collation
SELECT CodePoint, Symbol
FROM #CodePage
WHERE Symbol LIKE '[0123456789]' COLLATE Latin1_General_CS_AS
Best Answer
No. Collation is about alphabetical sorting, depending on code page, accent, case, width, kana. Numbers characters (0-9) have none of there properties.
So
9
is always after10B
in any sort.You have to split it up as you noted
or sort like this:The length in the right determines how many spaces you have.You could of course:
right justify in a char (a stored version of my RIGHT above)The latter 2 suggestions are like my RIGHT above and slightly different. Quicker to sort (no processing of the colukmn needed) but more storage required