Showing posts with label guess. Show all posts
Showing posts with label guess. Show all posts

Friday, March 23, 2012

Is there a "hack" that would allow you to reuse identity numbers that were orphaned by

I guess this is a fairly common topic but couldn't find the right words to find anything in a search.

What I'm getting at, is there any tsql functions or combination of commands for the following.

You have identity columns in your tables, if you set the a seed and autoincrement, I enter in rows 1 -10 and then I delete 4, 6, 7, 8.

My next new record uses 11. Is there any logic that allows you to check and reuse 4, 6, 7 & 8 described above? Not looking for something that consists of having to create an extra ID table for each table and handle configuring what the next available number is everytime an Insert or delete is called.

Thanks.

There is no built-in method to use gaps in identity values. You will have to write your own SQL code to do that. Please take a look at the script for a method to identity gaps in sequences.

CREATE TABLE #t ( seq int identity );
WHILE( SELECT COALESCE( MAX( seq ) , 0 ) FROM #t ) < 18
INSERT #t DEFAULT VALUES
DELETE #t WHERE seq%3 = 0
DELETE #t WHERE seq = 11
go
SELECT * FROM #t
-- Sample data:
/*
seq
--
1
2
4
5
7
8
10
13
14
16
17
*/

SELECT a.seq AS GapAfterSeq
FROM #t a
WHERE NOT EXISTS( SELECT * FROM #t b
WHERE b.seq = a.seq + 1 ) and
a.seq < ( SELECT MAX( seq ) FROM #t )
/*
GapAfterSeq
--
2
5
8
10
14
*/

-- Setup more sample data for boundary condition for test below:
DELETE #t WHERE seq = 1
SELECT * FROM #t
/*
seq
--
2
4
5
7
8
10
13
14
16
17
*/
GO

/*
This is a very generic form of query that can be used to
determine a gap given a range. The above query cannot
determine if a value is not present & is less than the existing
minimum value. Hence, this form of the query can handle that
boundary conditions too.
*/
DECLARE @.rangemin int , @.rangemax int
SELECT @.rangemin = 1 , @.rangemax = 20

SELECT MIN( seq ) + 1 AS NextSeq
FROM (
SELECT @.rangemin - 1 AS seq
WHERE NOT EXISTS( SELECT * FROM #t WHERE seq = @.rangemin )
UNION ALL
SELECT a.seq
FROM #t a
WHERE NOT EXISTS( SELECT * FROM #t b
WHERE b.seq = a.seq + 1 And
b.seq BETWEEN @.rangemin And @.rangemax ) And
a.seq >= @.rangemin And a.seq < @.rangemax
) AS t

/*
NextSeq
--
1
*/
GO
DROP TABLE #t;
GO

|||

In addition to what Umachandar said, it is a general best practice that if you care about the values that will be used, don't use identities. Because of the way the are implemented (basically to be a high performance, high concurrency method of creating a unique value) it is way too much to work with them in this way. They are best for a surrogate key that is usually not shown to the client (or they may want to change it :)

Louis

Is there a "hack" that would allow you to reuse identity numbers that were orphane

I guess this is a fairly common topic but couldn't find the right words to find anything in a search.

What I'm getting at, is there any tsql functions or combination of commands for the following.

You have identity columns in your tables, if you set the a seed and autoincrement, I enter in rows 1 -10 and then I delete 4, 6, 7, 8.

My next new record uses 11. Is there any logic that allows you to check and reuse 4, 6, 7 & 8 described above? Not looking for something that consists of having to create an extra ID table for each table and handle configuring what the next available number is everytime an Insert or delete is called.

Thanks.

There is no built-in method to use gaps in identity values. You will have to write your own SQL code to do that. Please take a look at the script for a method to identity gaps in sequences.

CREATE TABLE #t ( seq int identity );
WHILE( SELECT COALESCE( MAX( seq ) , 0 ) FROM #t ) < 18
INSERT #t DEFAULT VALUES
DELETE #t WHERE seq%3 = 0
DELETE #t WHERE seq = 11
go
SELECT * FROM #t
-- Sample data:
/*
seq
--
1
2
4
5
7
8
10
13
14
16
17
*/

SELECT a.seq AS GapAfterSeq
FROM #t a
WHERE NOT EXISTS( SELECT * FROM #t b
WHERE b.seq = a.seq + 1 ) and
a.seq < ( SELECT MAX( seq ) FROM #t )
/*
GapAfterSeq
--
2
5
8
10
14
*/

-- Setup more sample data for boundary condition for test below:
DELETE #t WHERE seq = 1
SELECT * FROM #t
/*
seq
--
2
4
5
7
8
10
13
14
16
17
*/
GO

/*
This is a very generic form of query that can be used to
determine a gap given a range. The above query cannot
determine if a value is not present & is less than the existing
minimum value. Hence, this form of the query can handle that
boundary conditions too.
*/
DECLARE @.rangemin int , @.rangemax int
SELECT @.rangemin = 1 , @.rangemax = 20

SELECT MIN( seq ) + 1 AS NextSeq
FROM (
SELECT @.rangemin - 1 AS seq
WHERE NOT EXISTS( SELECT * FROM #t WHERE seq = @.rangemin )
UNION ALL
SELECT a.seq
FROM #t a
WHERE NOT EXISTS( SELECT * FROM #t b
WHERE b.seq = a.seq + 1 And
b.seq BETWEEN @.rangemin And @.rangemax ) And
a.seq >= @.rangemin And a.seq < @.rangemax
) AS t

/*
NextSeq
--
1
*/
GO
DROP TABLE #t;
GO

|||

In addition to what Umachandar said, it is a general best practice that if you care about the values that will be used, don't use identities. Because of the way the are implemented (basically to be a high performance, high concurrency method of creating a unique value) it is way too much to work with them in this way. They are best for a surrogate key that is usually not shown to the client (or they may want to change it :)

Louis

Friday, March 9, 2012

Is server downgrade possible?

Hello,
my question is simple, i guess, if anyone can help me solve this problem:
I just installed Windows 2003 SBS Premium R2 but i have a software using SQL Server 2000 and not the one included in this version, 2005 wich is not compatible with. How can i downgrade, where cand i get the older server if the downgrade is possible and what else can i do before i shoot myself? Is there any license issue that will not allow me the downgrade?
Thank You!!!
SBS Premium R2 comes with 2005, but prior releases came with 2000. So, I would try to uninstall 2005 and reinstall 2000 with your install disks for the prior release.

Alternatively, you can install an MSDE instance on the same server and have it host your SQL 2000 database.

As I understand, however, if the install process for R2 upgraded the database itself, then you can't downgrade the database. Rather, you'd have to restore the most recent backup of the 2000 database.
|||Well, i don't have an older SQL 2000 database backup (also don't have a prior SBS 2003 server release) because we never used SQL before, version 2005 is uninstalled already but i don't know where from to download/get the SQL 2000 server as long as "Microsoft's ways" are a big mistery to me... if someone can drop a link for the SQL 2000 server would be great, just any version of the SQL 2000 that will work/install fine on our version of Windows, our software can't use the SQL 2005 included in SBS Premium 2003 R2, that's why i'm in trouble, nobody told me that before buying this license...
Many Thanks
|||

Don't you love it when they omit the details!

Here's a link to MSDE 2000 download...

http://www.microsoft.com/downloads/details.aspx?FamilyID=413744D1-A0BC-479F-BAFA-E4B278EB9147&displaylang=en

MSDE is the equivalent of SQL Server 2000 Engine, but other features are limited or not supported in the free version. For instance, performance is "throttled" after a certain number of users (about 16?) connect. If you don't know if those features are required by your database / application, I guess it's worth a try anyway. You can manage a SQL 2000 instance with SSMS that comes with SQL 2005.

Good luck...

Del

Is server downgrade possible?

Hello,
my question is simple, i guess, if anyone can help me solve this problem:
I just installed Windows 2003 SBS Premium R2 but i have a software using SQL Server 2000 and not the one included in this version, 2005 wich is not compatible with. How can i downgrade, where cand i get the older server if the downgrade is possible and what else can i do before i shoot myself? Is there any license issue that will not allow me the downgrade?
Thank You!!!SBS Premium R2 comes with 2005, but prior releases came with 2000. So, I would try to uninstall 2005 and reinstall 2000 with your install disks for the prior release.

Alternatively, you can install an MSDE instance on the same server and have it host your SQL 2000 database.

As I understand, however, if the install process for R2 upgraded the database itself, then you can't downgrade the database. Rather, you'd have to restore the most recent backup of the 2000 database.|||Well, i don't have an older SQL 2000 database backup (also don't have a prior SBS 2003 server release) because we never used SQL before, version 2005 is uninstalled already but i don't know where from to download/get the SQL 2000 server as long as "Microsoft's ways" are a big mistery to me... if someone can drop a link for the SQL 2000 server would be great, just any version of the SQL 2000 that will work/install fine on our version of Windows, our software can't use the SQL 2005 included in SBS Premium 2003 R2, that's why i'm in trouble, nobody told me that before buying this license...
Many Thanks|||

Don't you love it when they omit the details!

Here's a link to MSDE 2000 download...

http://www.microsoft.com/downloads/details.aspx?FamilyID=413744D1-A0BC-479F-BAFA-E4B278EB9147&displaylang=en

MSDE is the equivalent of SQL Server 2000 Engine, but other features are limited or not supported in the free version. For instance, performance is "throttled" after a certain number of users (about 16?) connect. If you don't know if those features are required by your database / application, I guess it's worth a try anyway. You can manage a SQL 2000 instance with SSMS that comes with SQL 2005.

Good luck...

Del

Monday, February 20, 2012

Is my beloved TSEQUAL() officially dead in 2005?

It seems my much loved TSEQUAL function was finally buried in SQL 2005.
Unless someone can suggest something better I guess I'm going to have to
resort to something like the code below. Any other suggestions would be
greatly apprieciated. I'll probably create a custom message to replace 532
so I can at least raise a consistent error. Anybody know the story behind
the demise of TSEQUAL? I know it's been undocumented for a while, but I was
always quite fond of it myself and came to rely on it. I know it's a sin to
depend on undocumented features, but it was just so handy I couldn't resist.
CREATE TABLE a(id int, col1 int, TS TIMESTAMP)
INSERT a (id, col1) VALUES(1,1)
DECLARE @.TS TIMESTAMP
DECLARE @.id INT
DECLARE @.RowCount INT
DECLARE @.Error INT
SELECT @.ID = id, @.TS = ts FROM a WHERE id = 1
--UPDATE a SET col1 = 2 WHERE id = @.id
--DELETE a WHERE id = @.id
UPDATE a SET col1 = 2 WHERE id = @.id AND TS = @.TS
SELECT @.Error = @.@.ERROR,
@.RowCount = @.@.ROWCOUNT
IF(@.Error = 0)
BEGIN
IF(@.RowCount = 0)
BEGIN
IF EXISTS(SELECT * FROM a WHERE id = @.id)
RAISERROR('Row not updated because it was changed', 16, 1)
ELSE
RAISERROR('Row is gone', 16, 1)
END
ELSE
PRINT 'Row updated'
END
ELSE
PRINT 'Error'Byron,
While I don't recommend TSEQUAL, which is undocumented,
it is available in my version of SQL Server 2005, and in fact, it
works better than in 2000. A bug I noted here
http://groups.google.com/groups/sea...al+useful+skass
is fixed.
Can you post a repro to show that it fails? Here is a repro where it
works for me:
if tsequal(2,2) select 1
if tsequal(-1, 33) select 1
Result in 2005 (version 9.00.2047.00):
1
Server: Msg 532, Level 16, State 2, Line 2
The timestamp (changed to 0x00000000ffffffff) shows that the row has
been updated by another user.
Result in 2000 (note extra result set):
1
Server: Msg 532, Level 16, State 2, Line 2
The timestamp (changed to 0x00000000ffffffff) shows that the row has
been updated by another user.
1
Byron wrote:

>It seems my much loved TSEQUAL function was finally buried in SQL 2005.
>Unless someone can suggest something better I guess I'm going to have to
>resort to something like the code below. Any other suggestions would be
>greatly apprieciated. I'll probably create a custom message to replace 532
>so I can at least raise a consistent error. Anybody know the story behind
>the demise of TSEQUAL? I know it's been undocumented for a while, but I wa
s
>always quite fond of it myself and came to rely on it. I know it's a sin t
o
>depend on undocumented features, but it was just so handy I couldn't resist
.
>CREATE TABLE a(id int, col1 int, TS TIMESTAMP)
>INSERT a (id, col1) VALUES(1,1)
>DECLARE @.TS TIMESTAMP
>DECLARE @.id INT
>DECLARE @.RowCount INT
>DECLARE @.Error INT
>SELECT @.ID = id, @.TS = ts FROM a WHERE id = 1
>--UPDATE a SET col1 = 2 WHERE id = @.id
>--DELETE a WHERE id = @.id
>UPDATE a SET col1 = 2 WHERE id = @.id AND TS = @.TS
>SELECT @.Error = @.@.ERROR,
> @.RowCount = @.@.ROWCOUNT
>IF(@.Error = 0)
>BEGIN
> IF(@.RowCount = 0)
> BEGIN
> IF EXISTS(SELECT * FROM a WHERE id = @.id)
> RAISERROR('Row not updated because it was changed', 16, 1)
> ELSE
> RAISERROR('Row is gone', 16, 1)
>END
>ELSE
> PRINT 'Row updated'
>END
>ELSE
>PRINT 'Error'
>
>|||Apparently you don't need it anymore (according to John Gallardo of the SQL
Server Engine team, in this thread:
http://sqljunkies.com/Forums/ShowPost.aspx?PostID=2534)
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
--
"Byron" <Byron@.discussions.microsoft.com> wrote in message
news:B43733C4-57BA-41EE-B932-8F17A1B29065@.microsoft.com...
> It seems my much loved TSEQUAL function was finally buried in SQL 2005.
> Unless someone can suggest something better I guess I'm going to have to
> resort to something like the code below. Any other suggestions would be
> greatly apprieciated. I'll probably create a custom message to replace
> 532
> so I can at least raise a consistent error. Anybody know the story behind
> the demise of TSEQUAL? I know it's been undocumented for a while, but I
> was
> always quite fond of it myself and came to rely on it. I know it's a sin
> to
> depend on undocumented features, but it was just so handy I couldn't
> resist.
> CREATE TABLE a(id int, col1 int, TS TIMESTAMP)
> INSERT a (id, col1) VALUES(1,1)
> DECLARE @.TS TIMESTAMP
> DECLARE @.id INT
> DECLARE @.RowCount INT
> DECLARE @.Error INT
> SELECT @.ID = id, @.TS = ts FROM a WHERE id = 1
> --UPDATE a SET col1 = 2 WHERE id = @.id
> --DELETE a WHERE id = @.id
> UPDATE a SET col1 = 2 WHERE id = @.id AND TS = @.TS
> SELECT @.Error = @.@.ERROR,
> @.RowCount = @.@.ROWCOUNT
> IF(@.Error = 0)
> BEGIN
> IF(@.RowCount = 0)
> BEGIN
> IF EXISTS(SELECT * FROM a WHERE id = @.id)
> RAISERROR('Row not updated because it was changed', 16, 1)
> ELSE
> RAISERROR('Row is gone', 16, 1)
> END
> ELSE
> PRINT 'Row updated'
> END
> ELSE
> PRINT 'Error'
>