Click here to Skip to main content
15,889,909 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi

I have Storeprocedure to generate dynamic menu based on group privilege
I have table for group privilege

USERID VARCHAR(10)
PRIVILEGEID VARCHAR(150)

It is working fine when privilegeID is less than 30 charactor

Currently, I have more then 80 charactor
If Exceeding 30, the error "Arithmetic overflow error converting varchar to data type numeric"

Pls advice how to overcome this issue

Maideen

Below is My SP

SQL
GO
/****** Object:  StoredProcedure [dbo].[W_usp_MENU_access]    Script Date: 15/08/2015 12:43:49 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

--Stored Procedure : 
ALTER PROCEDURE [dbo].[W_usp_MENU_access]
	@UserID [varchar](50)
WITH EXECUTE AS CALLER
AS
BEGIN

   CREATE TABLE #TMP(MenuID INT, Text VARCHAR(50), Description VARCHAR(50), ParentID INT, NavigateUrl VARCHAR(100))
    DECLARE @VAL VARCHAR(MAX), @Pos INT, @len INT
    SET @VAL=(SELECT REPLACE(REPLACE(CONVERT(VARCHAR(150), SUM(CAST(PrivilegeID AS 
        NUMERIC(30, 0)))), '2', '1'), '3', '1') FROM tblGroupPrivMst WHERE GroupCode 
        in (SELECT GroupCode FROM tblUserGrpMap WHERE UserID=@UserID))
		
    SET @Pos=1
    SET @len=LEN(@VAL)
    WHILE(@len!=0)
	
    BEGIN
        DECLARE @Value CHAR(1)
        SET @Value=SUBSTRING(@VAL, @Pos, 1)
		
        IF @Value=1
        BEGIN
            --PRINT @Value
            INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID=@Pos
        END
        SET @Pos=@Pos+1
        SET @len=@len-1
    END
    --For first Node (Inserting The Parent Node)
    INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID IN(SELECT DISTINCT 
      ParentID FROM #TMP WHERE ParentID NOT IN(SELECT MenuID FROM #TMP))
    --For second Node (Inserting The Parent Node)
    INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID IN(SELECT DISTINCT 
      ParentID FROM #TMP WHERE ParentID NOT IN(SELECT MenuID FROM #TMP))
    --For third Node (Inserting The Parent Node)
    INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID IN(SELECT DISTINCT 
      ParentID FROM #TMP WHERE ParentID NOT IN(SELECT MenuID FROM #TMP))
    SELECT * FROM #TMP ORDER BY MenuID ASC
    DROP TABLE #TMP
END
Posted

1 solution

In my opinion the first problem is that you're using varchar for numeric data. You should always use native types like bigint or float or similar when storing data.

The limit of 30 numbers comes from your conversion
SQL
CAST(PrivilegeID AS NUMERIC(30, 0))

You could try with
SQL
CAST(PrivilegeID AS FLOAT(53))


However I would suggest modifying the underlying data types.

Concerning the fact that the field is 150 characters long and named as an ID, why make the conversion to number at all. If the purpose is to identify something you don't need to calculate with it.

If you need to have a unique ID and the number of records is large, I would suggest using another kind of approach than just simple numbers. For example you could use a GUID as an identifier.
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 15-Aug-15 1:26am    
Of course, a 5. Strictly speaking, the answer is: with this approach, the problem cannot be avoided. An arbitrary string of given length can be interpreted as integer or not at all, cause overflow or not.
—SA
Wendelius 15-Aug-15 1:29am    
That's true. A string named PrivilegeID containing a maximum of 150 numbers is an ID, not somenthing you calculate with. IMHO the conversion shouldn't take place at all. Answer updated.
Sergey Alexandrovich Kryukov 15-Aug-15 1:46am    
Agree.
—SA
Maideen Abdul Kader 15-Aug-15 3:09am    
Mr.Wendelius
Thank for your reply

I have changed as per instruction, But another error message
"Conversion failed when converting the varchar value '.' to data type int"

Pls advice me

Maideen
Maideen Abdul Kader 15-Aug-15 3:19am    
Mr.Wendelius

Also I have tried Only this part
(SELECT REPLACE(REPLACE(CONVERT(VARCHAR(150), SUM(CAST(PrivilegeID AS
FLOAT(53)))), '2', '1'), '3', '1') FROM tblGroupPrivMst WHERE GroupCode
in (SELECT GroupCode FROM tblUserGrpMap WHERE UserID='maid'))

"maid" is user login id

But result is '1.11111e+051' But it should be "1010100001000101111100001000000000000000000000000000"
Pls advice me

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900