Showing posts with label hand. Show all posts
Showing posts with label hand. Show all posts

Friday, March 9, 2012

Don't want to use cursors but no way around it

During my long SQL-carreer I've managed to steer clear of Cursors. But now I have a project at hand where I do not see a feasable way to NOT use a cursor.

From a pool of available numbers (IMSIs) I need to allocate new ones and add them to a batch table. In total there are three tables affected by the following SP. A batch table storing info on the batch, a table that contains the newly allocated IMSIs and a table holding all IMSIs with a state field to indicate that they are free or not. With in the WHILE loop I need to set the state from 'F'(ree) to 'A'llocated and I have no clue how to update the ImsiCursor. So two questions:
Can this be done without a cursor?
How to update the State attribute of the current cursor location?

ALTER PROCEDURE dbo.spCreateBatch
(
@.BatchID AS int
, @.BatchSize AS int
, @.ImsiCount as smallint
, @.PurchaseOrder AS varchar(12)
)
AS
DECLARE @.counter5 AS char(5)
DECLARE @.FreeIMSIs AS BIGINT
SELECT @.FreeIMSIs = COUNT(Imsi) FROM tblImsiPool WHERE ImsiRangeID=1 AND STATE='F'
IF @.FreeIMSIs < @.BatchSize
BEGIN
RAISERROR ('Not enough free IMSIs in range', 16, 1)
RETURN
END

DECLARE ImsiCursor CURSOR LOCAL FORWARD_ONLY FOR SELECT p.Imsi, p.State FROM tblImsiPool p WHERE p.ImsiRangeID=1 AND p.State='F'

SET NOCOUNT ON
BEGIN TRANSACTION CreateBatch
DECLARE @.BatchID5 AS CHAR(5)
SET @.BatchID5 = RTRIM(LTRIM(@.BatchID))
SET @.BatchID5 = REPLICATE('0', 5 - LEN(@.BatchID5)) + RTRIM(@.BatchID5)
INSERT INTO
tblBatch (BatchID, Vendor, Creation, Required, BatchSize, ImsiCount, PurchaseOrder, PIN1Default, PIN2Default, MBPINDefault, State)
VALUES (@.BatchID5, 'GA', DEFAULT, DATEADD(m, 1, GETDATE()), @.BatchSize, @.ImsiCount, @.PurchaseOrder, 'RANDOM', 'RANDOM', 'RANDOM','C')
DECLARE @.counter AS int
DECLARE @.IccIDBase AS VARCHAR(19)
DECLARE @.IccID AS VARCHAR(20)
DECLARE @.Imsi AS NUMERIC(15)
DECLARE @.state AS CHAR(1)
SELECT @.Imsi = MAX(DefaultImsi) FROM tblSim

OPEN ImsiCursor
FETCH NEXT FROM ImsiCursor INTO @.Imsi, @.State

SET @.counter = 0
WHILE( @.counter <= @.BatchSize )
BEGIN
SET @.counter5 = @.counter
SET @.counter5 = REPLICATE('0', 5 - LEN(RTRIM(@.counter5))) + RTRIM(@.counter5)
SET @.IccIDBase = '89234507' + @.BatchID5 + @.counter5
SET @.IccID = RTRIM(@.IccIDBase) + CONVERT( CHAR(1), dbo.luhn( @.IccIDBase ) )
IF LEN(@.IccID) < 20
SET @.IccID = @.IccID + 'F'

INSERT INTO tblSIM(BatchID, Vendor, ICCID, Pin, Puk, Pin2, Puk2, DefaultImsi)
VALUES( @.BatchID5, 'GA', @.IccID, '', '', '', '', @.Imsi)

UPDATE ImsiCursor SET State = 'A' -- does not work
FETCH NEXT FROM ImsiCursor INTO @.Imsi, @.State

SET @.counter = @.counter + 1
END

CLOSE ImsiCursor
DEALLOCATE ImsiCursor


IF @.@.ERROR = 0
COMMIT TRANSACTION CreateBatch
ELSE
ROLLBACK TRANSACTION CreateBatch

RETURN

From what you have said, it seems reasonable that you could do this without cursors, buit it might be tricky.

You would just do an update to set the number of rows you want to allocate to not allocated (then in 2005, you can use the OUTPUT clause to get the rows you changed, or you can lock the rows with a SELECT into your temp table and and XLOCK in a transaction).

Now it looks like this code:

SET @.counter5 = @.counter
SET @.counter5 = REPLICATE('0', 5 - LEN(RTRIM(@.counter5))) + RTRIM(@.counter5)
SET @.IccIDBase = '89234507' + @.BatchID5 + @.counter5
SET @.IccID = RTRIM(@.IccIDBase) + CONVERT( CHAR(1), dbo.luhn( @.IccIDBase ) )
IF LEN(@.IccID) < 20
SET @.IccID = @.IccID + 'F'

INSERT INTO tblSIM(BatchID, Vendor, ICCID, Pin, Puk, Pin2, Puk2, DefaultImsi)
VALUES( @.BatchID5, 'GA', @.IccID, '', '', '', '', @.Imsi)

Is the meat of the query. You could probably translated the variable to calculations in a SELECT query.

It is all too messy to work with for the uneducated. Please post some sample data and minimal tables that just cover the problems you are having and it will be easier to demonstrate.

Friday, February 17, 2012

DOH! Uninstall of 2005 gone horribly wrong

I am an old hand at RDBMS but have been using SQL Server for only 1 year. I have a local install of 2005 Developer Edition, and also access a number of 2000 and 2005 instances on remote and network servers. OK, so on 3/16 (after installing the 3/15 Windows Security Updates), I began getting this error when invoking any 2005 DB under Object Explorer in Management Studio "SQLWB - SQL Server Management Studio has encountered a problem and needs to close. We are sorry for the inconvenience." Very helpful. So I ran a debug and got some unhandled exception errors:

'SqlWb.exe': Loaded 'C:\WINDOWS\system32\wbem\wbemsvc.dll', No symbols loaded.
'SqlWb.exe': Loaded 'C:\WINDOWS\system32\wbem\fastprox.dll', No symbols loaded.
'SqlWb.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\diasymreader.dll', No symbols loaded.
'SqlWb.exe': Loaded 'C:\WINDOWS\system32\apphelp.dll', No symbols loaded.
The thread 'Win32 Thread' (0x21c) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0xa98) has exited with code 0 (0x0).
Unhandled exception at 0x79ea69f3 in SqlWb.exe: 0xC0000006: In page error.
First-chance exception at 0x79ea69f3 in SqlWb.exe: 0xC0000005: Access violation reading location 0x088b200c.
Unhandled exception at 0x79ea69f3 in SqlWb.exe: 0xC0000005: Access violation reading location 0x088b200c.
First-chance exception at 0x79ea69f3 in SqlWb.exe: 0xC0000005: Access violation reading location 0x088b200c.

After some poking around, my DBA told me that we had upgraded the servers for our team to SP1, and I should install that, because the file being read did not 'match up' with the commands. But when I did so I got the warning:

- Edition Change Check (Warning)

Messages

Edition Change Check

To change an existing instance of Microsoft SQL Server 2005 to a different edition of SQL Server 2005, you must run SQL Server 2005 Setup from the command prompt and include the SKUUPGRADE=1 parameter.

I researched this information, but it didn't really apply to my situation. So I selected 'CONTINUE' and everything went downhill from there. The install downloaded the SP1 setup support files (which by the way "cannot be removed") and then aborted. I poked around some more and decided it would be easiest to Uninstall and Reinstall the Dev Edition from the DVD and then apply the SP. The uninstall went fine until it got to the tools (which apparently were my real problem to start with). When I attempt to uninstall the tools, I get the following message:

"Error reading from file C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.SqlEnum\9.0.242.0__89845dcd8080cc91\Microsoft.SqlServer.SqlEnum.dll

Verify that this file exists and that you can access it"

This message is presented with Retry and Cancel options. The file does NOT exist, so Retry is not useful and cancel rolls back the entire uninstall.

Error signature:

EventType : sql90setup P1 : installfinalize P2 : 0x643 P3 : unknown
P4 : 0x519 P5 : unknown P6 : unknown
P7 : sqlrun_tools.msi@.9.00.1399.06

In this part SP1/half uninstalled 2005 environment I am stuck like chuck. I have searched for this dll online and on other folders of my hard drive to no avail. I have also dug through these forums until my eyes are crossed.

Can anyone help?!?

One more search location turned up the answer here: http://support.microsoft.com/default.aspx/kb/909953

Turns out the tools are considered components. You can remove services and instances from the REMOVE dialog, but you have to CHANGE the client components (under workstation components) and de-select Management Tools.

I cannot believe how long it took me to find this; I finally found it today in the setup help information on the install DVD while preparing for the install. I'll leave this here for others who check the boards before the knowledge base.

THANKS to anyone who put thought into this today.

|||

Thanks for following up your own post. It prevents others from wasting their time trying to help you after you have solved the problem, and it helps others when you share your solution.