ALM123
asked on
SQL slow when updating large number of records
Hi,
Im a newbie to SQL but have been struggling with this for a while:
I have a large table(approx 2M records) as shown below called test. I have to strip the eighth digit and add one to the seventh digit. Then pass the new number into my stored procedure which will then create a new eighth digit. My attached script works but is far too slow for what is required. Id_no is the primary key which has a clustered index.
Things tried.
Adding extra indexes.
Used integer instead of varchar and converted back where necessary.
Test
Id_no number_1 number_2
Int(PK) varchar(8) varchar(6)
29067783 36324323 630502
29067795 00856389 311518
29067803 30505702 218968
29067811 80731375 295942
29067816 13262414 540058
29067817 52513434 534148
29067829 96974118 545003
29067831 70515700 234324
29067836 00846489 201148
29067840 20716619 106305
Reading other articles suggest using a cursor is not the best idea but it seemed easiest as Id_no is not sequential. Currently it is taking 9 mins to update 10k records. If I remove the call to my stored procedure the update is still taking over a minute. If I remove both then the script takes 3 seconds.
Any help greatly appreciated!
Im a newbie to SQL but have been struggling with this for a while:
I have a large table(approx 2M records) as shown below called test. I have to strip the eighth digit and add one to the seventh digit. Then pass the new number into my stored procedure which will then create a new eighth digit. My attached script works but is far too slow for what is required. Id_no is the primary key which has a clustered index.
Things tried.
Adding extra indexes.
Used integer instead of varchar and converted back where necessary.
Test
Id_no number_1 number_2
Int(PK) varchar(8) varchar(6)
29067783 36324323 630502
29067795 00856389 311518
29067803 30505702 218968
29067811 80731375 295942
29067816 13262414 540058
29067817 52513434 534148
29067829 96974118 545003
29067831 70515700 234324
29067836 00846489 201148
29067840 20716619 106305
Reading other articles suggest using a cursor is not the best idea but it seemed easiest as Id_no is not sequential. Currently it is taking 9 mins to update 10k records. If I remove the call to my stored procedure the update is still taking over a minute. If I remove both then the script takes 3 seconds.
Any help greatly appreciated!
BEGIN
DECLARE
@number2 varchar(6)
,@number1 varchar(8)
,@Id_no int
,@new_no varchar(8)
,@new_no_2 varchar(8)
,@log_count int
,@trans_max int
,@end_of_csr varchar(1)
,@count int
SET NOCOUNT ON
SET @log_count = 0
SET @trans_max = 200
set @end_of_csr = 'N'
set @count=0
BEGIN TRANSACTION
DECLARE csr_test cursor
FOR
(
SELECT
Id_no ,number_2,number_1
FROM
Test
)
COMMIT TRANSACTION
OPEN csr_test
WHILE @end_of_csr = 'N'
BEGIN
FETCH NEXT FROM csr_test
INTO
@Id_no,
@number2,
@number1
--if @Id_no = 27291669
--begin
-- SET @end_of_csr = 'Y'
--end
IF @@FETCH_STATUS <> 0
BEGIN
SET @end_of_csr = 'Y'
END
SET @new_no = LEFT(@number1,7)
SET @new_no = CAST(@new_no as int) + 1
IF LEN(@new_no ) = 4
BEGIN
SET @new_no = '000'+ @new_no
END
IF LEN(@new_no ) = 5
BEGIN
SET @new_no = '00' + @new_no
END
IF LEN(@new_no ) = 6
BEGIN
SET @new_no = '0' + @new_no
END
SET @count=@count+1
BEGIN TRANSACTION
SET @log_count = @log_count + 1
IF @log_count > @trans_max
BEGIN --TRANSACTION
SET @log_count = 1
END
EXEC usp_mystoredproc @number2, @new_no , @new_no_2 OUTPUT
IF LEN(@new_no_2) = 3
BEGIN
SET @new_no_2 = '00000'+ @new_no_2
END
IF LEN(@new_no_2) = 4
BEGIN
SET @new_no_2 = '0000'+ @new_no_2
END
IF LEN(@new_no_2) = 5
BEGIN
SET @new_no_2 = '000' + @new_no_2
END
IF LEN(@new_no_2) = 6
BEGIN
SET @new_no_2 = '00' + @new_no_2
END
IF LEN(@new_no_2) = 7
BEGIN
SET @new_no_2 = '0' + @new_no_2
END
PRINT 'updating account ' + CAST(@new_no AS VARCHAR(8)) + ' ' + CAST(@Id_no AS VARCHAR(10))+ ' from ' + CAST(@number1 AS VARCHAR(8))+ ' '+CAST(@number2 AS VARCHAR(7))+ ' ' + cast(@COUNT as VARCHAR(9))
--UPDATE Test SET number_1 = @new_no
--WHERE [Id_no] = @Id_no
UPDATE Test
SET number_1 = @new_no2
WHERE CURRENT of csr_test
COMMIT TRANSACTION
END
END
--SET statistics IO OFF
BEGIN
CLOSE csr_test
DEALLOCATE csr_test
END
sorry my solution just reduced the amount of processing and number of conditional tests being perform for each row ....
Hi,
Just somethign I noticed about Lowfat's code, shouldn't lines 28 and 43 yes left rather than right?
Cheers
David
Just somethign I noticed about Lowfat's code, shouldn't lines 28 and 43 yes left rather than right?
Cheers
David
don't think so he wants leading zeroes ?
e.g. right('00000' + 4567,8) = 00004567
e.g. right('00000' + 4567,8) = 00004567
but
SELECT top 1
@id_no= Id_no
,@number2=number_2
,@new_no=Right('0000'+conv ert(varcha r(7),conve rt(integer ,substring (number_1, 1,7))+1),7 )
,@count=@count+1
,@log_count=@log_count+1
FROM Test
where id_no >=@id_old
does require an order by to be added
e.g.
SELECT top 1
@id_no= Id_no
,@number2=number_2
,@new_no=Right('0000'+conv ert(varcha r(7),conve rt(integer ,substring (number_1, 1,7))+1),7 )
,@count=@count+1
,@log_count=@log_count+1
FROM Test
where id_no >=@id_old
order by id_no
SELECT top 1
@id_no= Id_no
,@number2=number_2
,@new_no=Right('0000'+conv
,@count=@count+1
,@log_count=@log_count+1
FROM Test
where id_no >=@id_old
does require an order by to be added
e.g.
SELECT top 1
@id_no= Id_no
,@number2=number_2
,@new_no=Right('0000'+conv
,@count=@count+1
,@log_count=@log_count+1
FROM Test
where id_no >=@id_old
order by id_no
ASKER
Hi,
Thanks for looking at this, Ive tested both above and stil seems to be taking about the same time. Ive attached the stored procedure to see if anyone can think of anything else. Many Thanks again. It is just performing some basic mod check function which I thought wouldnt take any time to process. Im open to using a function or anything really. Thanks again.
Thanks for looking at this, Ive tested both above and stil seems to be taking about the same time. Ive attached the stored procedure to see if anyone can think of anything else. Many Thanks again. It is just performing some basic mod check function which I thought wouldnt take any time to process. Im open to using a function or anything really. Thanks again.
CREATE PROCEDURE [dbo].[usp_moduluscheck2]
@number2 varchar(6)
,@number1 varchar(8)
,@new_number1 varchar(8) OUTPUT --varchar(8) OUTPUT
AS
DECLARE
@u SMALLINT -- Value for u
,@v SMALLINT
,@w SMALLINT
,@x SMALLINT
,@y SMALLINT
,@z SMALLINT
,@a SMALLINT
,@b SMALLINT
,@c SMALLINT
,@d SMALLINT
,@e SMALLINT
,@f SMALLINT
,@g SMALLINT
,@h SMALLINT
,@Wu SMALLINT -- weighting for u
,@Wv SMALLINT
,@Ww SMALLINT
,@Wx SMALLINT
,@Wy SMALLINT
,@Wz SMALLINT
,@Wa SMALLINT
,@Wb SMALLINT
,@Wc SMALLINT
,@Wd SMALLINT
,@We SMALLINT
,@Wf SMALLINT
,@Wg SMALLINT
,@Wh SMALLINT
,@ValidationId_no INT -- Weighting row currently being applied
,@Ctr INT -- loop counter
,@MaxCtr INT -- loop max value
,@ModCheck VARCHAR(5) -- 1 of 3 modulus check types
,@ModINT -- result of modulus(weightsum)
,@WeightSum INT -- Result of summing(weights)
,@Exception VARCHAR(3) -- exception rule for this weighting
,@number2a varchar(6)
,@number1a varchar(8)
,@new_number1a varchar(8)
--set @number2 = '515003'
--set @number1 = '9677412'
BEGIN
SET NOCOUNT ON
SET CONCAT_NULL_YIELDS_NULL OFF
IF OBJECT_ID('dbo.WR') IS NOT NULL
BEGIN
DROP TABLE [dbo].[WR]
END
CREATE TABLE [dbo].[WR]
(
[Id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY
,Id_no INT NOT NULL
)
INSERT INTO dbo.WR
(
Id_no
)
SELECT
v.Id_no
FROM
dbo.bank_validation v
INNER JOIN (
SELECT
starting_sortcode
,ending_sortcode
FROM
dbo.bank_validation
WHERE
@number2 BETWEEN starting_sortcode AND ending_sortcode
GROUP BY
starting_sortcode
,ending_sortcode
) c
ON
v.starting_sortcode = c.starting_sortcode
AND
v.ending_sortcode = c.ending_sortcode
ORDER BY
v.Id_no
--print @ValidationId_no
SELECT
@Ctr = MIN([Id])
,@MaxCtr = MAX([Id])
FROM
dbo.WR
SELECT
@ValidationId_no = Id_no
FROM
dbo.WR
WHERE
[Id] = @Ctr
-- Where two rows exist they must be performed in the order that they appear.
WHILE @Ctr <= @MaxCtr
BEGIN
SELECT
@Wu = weighting_string_1
,@Wv = weighting_string_2
,@Ww = weighting_string_3
,@Wx = weighting_string_4
,@Wy = weighting_string_5
,@Wz = weighting_string_6
,@Wa = weighting_string_7
,@Wb = weighting_string_8
,@Wc = weighting_string_9
,@Wd = weighting_string_10
,@We = weighting_string_11
,@Wf = weighting_string_12
,@Wg = weighting_string_13
,@Wh = weighting_string_14
,@ModCheck = algorithm
,@Exception = exception_code
FROM
dbo.bank_validation v
WHERE
v.Id_no = @ValidationId_no
--PRINT @ModCheck
--SET @number2 a=CONVERT(varchar,@number2 )
--SET @number1 a=CONVERT(varchar,@number1 )
SET @u = LEFT(@number2 ,1)
SET @v = SUBSTRING(@number2 ,2,1)
SET @w = SUBSTRING(@number2 ,3,1)
SET @x = SUBSTRING(@number2 ,4,1)
SET @y = SUBSTRING(@number2 ,5,1)
SET @z = SUBSTRING(@number2 ,6,1)
SET @a = LEFT(@number1 ,1)
SET @b = SUBSTRING(@number1 ,2,1)
SET @c = SUBSTRING(@number1 ,3,1)
SET @d = SUBSTRING(@number1 ,4,1)
SET @e = SUBSTRING(@number1 ,5,1)
SET @f = SUBSTRING(@number1 ,6,1)
SET @g = SUBSTRING(@number1 ,7,1)
SET @h = SUBSTRING(@number1 ,8,1)
DECLARE @calc1 int
,@calc2 int
IF @ModCheck = 'MOD10'
BEGIN -- MOD10 Check
SET @WeightSum =
(@u*@Wu)+(@v*@Wv)+(@w*@Ww)+(@x*@Wx)+(@y*@Wy)+(@z * @Wz)
(@a*@Wa)+(@b*@Wb)+(@c*@Wc)+(@d*@Wd)+(@e*@We)+(@f*@Wf)+(@g*@Wg)
SET @Mod= @WeightSum % 10
SET @calc1 = @WeightSum + 10 -@modulus
SET @calc2 = @calc1 - @WeightSum
END
IF @ModCheck = 'MOD11'
BEGIN
SET @WeightSum = (@u*@Wu)+(@v*@Wv)+(@w*@Ww)+(@x*@Wx)+(@y*@Wy)+(@z*@Wz) +
(@a*@Wa)+(@b*@Wb)+(@c*@Wc)+(@d*@Wd)+(@e*@We)+(@f*@Wf)+(@g*@Wg)+(@h*@Wh)
SET @Mod= @WeightSum % 11
SET @calc1 = @WeightSum + 11 -@modulus
SET @calc2 = @calc1 - @WeightSum
END
IF @ModCheck = 'DBLAL'
BEGIN -- DBLAL Check
SET @WeightSum =
CASE
WHEN (@u*@Wu) <= 9 THEN (@u*@Wu)
ELSE CAST(LEFT(CAST((@u*@Wu) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@u*@Wu) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@v*@Wv) <= 9 THEN (@v*@Wv)
ELSE CAST(LEFT(CAST((@v*@Wv) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@v*@Wv) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@w*@Ww) <= 9 THEN (@w*@Ww)
ELSE CAST(LEFT(CAST((@w*@Ww) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@w*@Ww) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@x*@Wx) <= 9 THEN (@x*@Wx)
ELSE CAST(LEFT(CAST((@x*@Wx) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@x*@Wx) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@y*@Wy) <= 9 THEN (@y*@Wy)
ELSE CAST(LEFT(CAST((@y*@Wy) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@y*@Wy) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@z*@Wz) <= 9 THEN (@z*@Wz)
ELSE CAST(LEFT(CAST((@z*@Wz) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@z*@Wz) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@a*@Wa) <= 9 THEN (@a*@Wa)
ELSE CAST(LEFT(CAST((@a*@Wa) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@a*@Wa) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@b*@Wb) <= 9 THEN (@b*@Wb)
ELSE CAST(LEFT(CAST((@b*@Wb) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@b*@Wb) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@c*@Wc) <= 9 THEN (@c*@Wc)
ELSE CAST(LEFT(CAST((@c*@Wc) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@c*@Wc) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@d*@Wd) <= 9 THEN (@d*@Wd)
ELSE CAST(LEFT(CAST((@d*@Wd) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@d*@Wd) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@e*@We) <= 9 THEN (@e*@We)
ELSE CAST(LEFT(CAST((@e*@We) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@e*@We) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@f*@Wf) <= 9 THEN (@f*@Wf)
ELSE CAST(LEFT(CAST((@f*@Wf) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@f*@Wf) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@g*@Wg) <= 9 THEN (@g*@Wg)
ELSE CAST(LEFT(CAST((@g*@Wg) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@g*@Wg) AS VARCHAR(12)),1) AS INT)
END
SET @Mod= @WeightSum % 10
SET @calc1 = @WeightSum + 10 - @modulus
SET @calc2 = @calc1 - @WeightSum
END
SET @new_number1= @number1 + CAST(@calc2 AS VARCHAR(1))
SET @Ctr = @Ctr + 1
END
END
TRUNCATE TABLE [dbo].[WR]
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
where is the @modulus actually set?
ASKER
Apologies right script this time
@NumberB varchar(6)
,@NumberA varchar(8)
,@New_numberA varchar(8) OUTPUT --varchar(8) OUTPUT
AS
DECLARE
@u SMALLINT -- Value for u
,@v SMALLINT
,@w SMALLINT
,@x SMALLINT
,@y SMALLINT
,@z SMALLINT
,@a SMALLINT
,@b SMALLINT
,@c SMALLINT
,@d SMALLINT
,@e SMALLINT
,@f SMALLINT
,@g SMALLINT
,@h SMALLINT
,@Wu SMALLINT -- weighting for u
,@Wv SMALLINT
,@Ww SMALLINT
,@Wx SMALLINT
,@Wy SMALLINT
,@Wz SMALLINT
,@Wa SMALLINT
,@Wb SMALLINT
,@Wc SMALLINT
,@Wd SMALLINT
,@We SMALLINT
,@Wf SMALLINT
,@Wg SMALLINT
,@Wh SMALLINT
,@ValidationId_no INT -- Weighting row currently being applied
,@Ctr INT -- loop counter
,@MaxCtr INT -- loop max value
,@ModCheck VARCHAR(5) -- 1 of 3 modulus check types
,@Mod INT -- result of modulus(weightsum)
,@WeightSum INT -- Result of summing(weights)
SET NOCOUNT ON
SET CONCAT_NULL_YIELDS_NULL OFF
--set @NumberB= '515003'
--set @NumberA= '9677412'
--set @New_numberA = ''
BEGIN
SET NOCOUNT ON
SET CONCAT_NULL_YIELDS_NULL OFF
IF OBJECT_ID('dbo.WR') IS NOT NULL
BEGIN
DROP TABLE [dbo].[WR]
END
CREATE TABLE [dbo].[WR]
(
[Id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY
,objid INT NOT NULL
)
INSERT INTO dbo.WR
(
ObjId
)
SELECT
v.ObjId
FROM
dbo.BV v
INNER JOIN (
SELECT
starting_sortcode
,ending_sortcode
FROM
dbo.BV
WHERE
@NumberB BETWEEN starting_sortcode AND ending_sortcode
GROUP BY
starting_sortcode
,ending_sortcode
) c
ON
v.starting_sortcode = c.starting_sortcode
AND
v.ending_sortcode = c.ending_sortcode
ORDER BY
v.objid
--print @ValidationId_no
SELECT
@Ctr = MIN([Id])
,@MaxCtr = MAX([Id])
FROM
dbo.WR
SELECT
@ValidationId_no = ObjId
FROM
dbo.WR
WHERE
[Id] = @Ctr
-- Where two rows exist they must be performed in the order that they appear.
WHILE @Ctr <= @MaxCtr
BEGIN
SELECT
@Wu = weighting_string_1
,@Wv = weighting_string_2
,@Ww = weighting_string_3
,@Wx = weighting_string_4
,@Wy = weighting_string_5
,@Wz = weighting_string_6
,@Wa = weighting_string_7
,@Wb = weighting_string_8
,@Wc = weighting_string_9
,@Wd = weighting_string_10
,@We = weighting_string_11
,@Wf = weighting_string_12
,@Wg = weighting_string_13
,@Wh = weighting_string_14
,@ModCheck = algorithm
FROM
dbo.BV v
WHERE
v.objid = @ValidationId_no
--PRINT @ModCheck
--SET @NumberBa=CONVERT(varchar,@NumberB)
--SET @NumberAa=CONVERT(varchar,@NumberA)
SET @u = LEFT(@NumberB,1)
SET @v = SUBSTRING(@NumberB,2,1)
SET @w = SUBSTRING(@NumberB,3,1)
SET @x = SUBSTRING(@NumberB,4,1)
SET @y = SUBSTRING(@NumberB,5,1)
SET @z = SUBSTRING(@NumberB,6,1)
SET @a = LEFT(@NumberA,1)
SET @b = SUBSTRING(@NumberA,2,1)
SET @c = SUBSTRING(@NumberA,3,1)
SET @d = SUBSTRING(@NumberA,4,1)
SET @e = SUBSTRING(@NumberA,5,1)
SET @f = SUBSTRING(@NumberA,6,1)
SET @g = SUBSTRING(@NumberA,7,1)
SET @h = SUBSTRING(@NumberA,8,1)
DECLARE @calc1 int
,@calc2 int
,@calc3 int
IF @ModCheck = 'MOD10'
BEGIN -- MOD10 Check
-- Multiply by the weight and add the results together
SET @WeightSum =
(@u*@Wu)+(@v*@Wv)+(@w*@Ww)+(@x*@Wx)+(@y*@Wy)+(@z * @Wz) + -- Sortcode
(@a*@Wa)+(@b*@Wb)+(@c*@Wc)+(@d*@Wd)+(@e*@We)+(@f*@Wf)+(@g*@Wg) -- account number
-- Divide the total by the modulus (10)
SET @Mod = @WeightSum % 10
SET @calc1 = @WeightSum + 10 -@Mod
SET @calc2 = @calc1 - @WeightSum
END
IF @ModCheck = 'MOD11'
BEGIN
SET @WeightSum = (@u*@Wu)+(@v*@Wv)+(@w*@Ww)+(@x*@Wx)+(@y*@Wy)+(@z*@Wz) +
(@a*@Wa)+(@b*@Wb)+(@c*@Wc)+(@d*@Wd)+(@e*@We)+(@f*@Wf)+(@g*@Wg)+(@h*@Wh)
-- Divide the total by the modulus (11)
SET @Mod = @WeightSum % 11
SET @calc1 = @WeightSum + 11 -@Mod
SET @calc2 = @calc1 - @WeightSum
END
IF @ModCheck = 'DBLAL'
BEGIN -- DBLAL Check
SET @WeightSum =
CASE
WHEN (@u*@Wu) <= 9 THEN (@u*@Wu)
ELSE CAST(LEFT(CAST((@u*@Wu) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@u*@Wu) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@v*@Wv) <= 9 THEN (@v*@Wv)
ELSE CAST(LEFT(CAST((@v*@Wv) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@v*@Wv) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@w*@Ww) <= 9 THEN (@w*@Ww)
ELSE CAST(LEFT(CAST((@w*@Ww) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@w*@Ww) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@x*@Wx) <= 9 THEN (@x*@Wx)
ELSE CAST(LEFT(CAST((@x*@Wx) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@x*@Wx) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@y*@Wy) <= 9 THEN (@y*@Wy)
ELSE CAST(LEFT(CAST((@y*@Wy) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@y*@Wy) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@z*@Wz) <= 9 THEN (@z*@Wz)
ELSE CAST(LEFT(CAST((@z*@Wz) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@z*@Wz) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@a*@Wa) <= 9 THEN (@a*@Wa)
ELSE CAST(LEFT(CAST((@a*@Wa) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@a*@Wa) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@b*@Wb) <= 9 THEN (@b*@Wb)
ELSE CAST(LEFT(CAST((@b*@Wb) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@b*@Wb) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@c*@Wc) <= 9 THEN (@c*@Wc)
ELSE CAST(LEFT(CAST((@c*@Wc) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@c*@Wc) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@d*@Wd) <= 9 THEN (@d*@Wd)
ELSE CAST(LEFT(CAST((@d*@Wd) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@d*@Wd) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@e*@We) <= 9 THEN (@e*@We)
ELSE CAST(LEFT(CAST((@e*@We) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@e*@We) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@f*@Wf) <= 9 THEN (@f*@Wf)
ELSE CAST(LEFT(CAST((@f*@Wf) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@f*@Wf) AS VARCHAR(12)),1) AS INT)
END +
CASE
WHEN (@g*@Wg) <= 9 THEN (@g*@Wg)
ELSE CAST(LEFT(CAST((@g*@Wg) AS VARCHAR(12)),1) AS INT) +
CAST(RIGHT(CAST((@g*@Wg) AS VARCHAR(12)),1) AS INT)
END
-- Divide the total by the modulus (10)
SET @Mod = @WeightSum % 10
SET @calc1 = @WeightSum + 10 - @Mod
SET @calc2 = @calc1 - @WeightSum
END
IF @ModCheck = 'MOD11' AND @calc2=11
BEGIN
SET @calc2 = 0
END
IF @ModCheck = 'MOD11' AND @calc2=10
BEGIN
SET @calc2 = 0
END
IF @ModCheck = 'MOD10' AND @calc2=10
BEGIN
SET @calc2 = 0
END
IF @ModCheck = 'DBLAL' AND @calc2=10
BEGIN
SET @calc2 = 0
END
SET @New_numberA= @NumberA+ CAST(@calc2 AS VARCHAR(1))
SET @Ctr = @Ctr + 1
END
END
TRUNCATE TABLE [dbo].[WR]
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Lowfatspread, do you think this can be done in a single update statement without loops or functions?
ASKER
Thats seems better. Thanks again.
i'm not sure you actually want the begin/commit trransctions...
yes don't use a cursor if avoidable...
can you convert the stored procedure into a function ?
in that case you could just use a single update statement...
hth
Open in new window