converting to INT from varchar

  • Hi, i have one of the parameter of my procedure as @Stores as varchar(2000) = null,

    which gets values like 325,785,5698 as inputs..

    now i need to query it against STORES table of STORE_ID (which is INT)

    i am doinf like and rh.STORE_ID in (@Stores)

    which is failing and giving me Conversion failed when converting the varchar value '325,785,5698' to data type int. error..

    could you please help me how to solve this...

  • Have you looked into using cast and or convert? http://msdn.microsoft.com/en-us/library/ms187928.aspx

  • whole (11/4/2011)


    Hi, i have one of the parameter of my procedure as @Stores as varchar(2000) = null,

    which gets values like 325,785,5698 as inputs..

    now i need to query it against STORES table of STORE_ID (which is INT)

    i am doinf like and rh.STORE_ID in (@Stores)

    which is failing and giving me Conversion failed when converting the varchar value '325,785,5698' to data type int. error..

    could you please help me how to solve this...

    I think this is what you're after -

    --Standard TestEnvironment of 1,000,000 rows of random-ish data

    IF object_id('tempdb..#testEnvironment') IS NOT NULL

    BEGIN

    DROP TABLE #testEnvironment

    END

    --1,000,000 Random rows of data

    SELECT TOP 1000000 IDENTITY(INT,1,1) AS ID,

    RAND(CHECKSUM(NEWID())) * 30000 + CAST('1945' AS DATETIME) AS randomDate,

    ABS(CHECKSUM(NEWID())) AS randomBigInt,

    (ABS(CHECKSUM(NEWID())) % 10000) + 1 AS randomMediumInt,

    (ABS(CHECKSUM(NEWID())) % 100) + 1 AS randomSmallInt,

    RAND(CHECKSUM(NEWID())) * 100 AS randomSmallDec,

    RAND(CHECKSUM(NEWID())) AS randomTinyDec,

    RAND(CHECKSUM(NEWID())) * 100000 AS randomBigDec,

    CONVERT(VARCHAR(6),CONVERT(MONEY,RAND(CHECKSUM(NEWID())) * 100),0) AS randomMoney

    INTO #testEnvironment

    FROM master.dbo.syscolumns sc1, master.dbo.syscolumns sc2, master.dbo.syscolumns sc3

    --Declare and set your "stores" variable

    DECLARE @Stores AS VARCHAR(2000)

    SET @Stores = '325,785,5698'

    --Build query

    DECLARE @query AS VARCHAR(MAX)

    SET @query = 'SELECT * FROM #testEnvironment

    WHERE randomMediumInt IN ('+@Stores+')'

    --Execute query

    EXEC(@query)


    Forever trying to learn
    My blog - http://www.cadavre.co.uk/
    For better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/
    For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Is there any way without using inline SQL.

  • Another method: -

    --Standard TestEnvironment of 1,000,000 rows of random-ish data

    IF object_id('tempdb..#testEnvironment') IS NOT NULL

    BEGIN

    DROP TABLE #testEnvironment

    END

    --1,000,000 Random rows of data

    SELECT TOP 1000000 IDENTITY(INT,1,1) AS ID,

    RAND(CHECKSUM(NEWID())) * 30000 + CAST('1945' AS DATETIME) AS randomDate,

    ABS(CHECKSUM(NEWID())) AS randomBigInt,

    (ABS(CHECKSUM(NEWID())) % 10000) + 1 AS randomMediumInt,

    (ABS(CHECKSUM(NEWID())) % 100) + 1 AS randomSmallInt,

    RAND(CHECKSUM(NEWID())) * 100 AS randomSmallDec,

    RAND(CHECKSUM(NEWID())) AS randomTinyDec,

    RAND(CHECKSUM(NEWID())) * 100000 AS randomBigDec,

    CONVERT(VARCHAR(6),CONVERT(MONEY,RAND(CHECKSUM(NEWID())) * 100),0) AS randomMoney

    INTO #testEnvironment

    FROM master.dbo.syscolumns sc1, master.dbo.syscolumns sc2, master.dbo.syscolumns sc3

    --Declare and set your "stores" variable

    DECLARE @Stores AS VARCHAR(2000)

    SET @Stores = '325,785,5698';

    --Query

    WITH Pieces(pn, start, stop) AS (

    SELECT 1, 1, CHARINDEX(',', @Stores)

    UNION ALL

    SELECT pn + 1, stop + 1, CHARINDEX(',', @Stores, stop + 1)

    FROM Pieces

    WHERE stop > 0)

    SELECT *

    FROM #testEnvironment

    WHERE randomMediumInt IN (SELECT SUBSTRING(@Stores, start, CASE WHEN stop > 0 THEN stop-start ELSE 2000 END) AS stores

    FROM Pieces)


    Forever trying to learn
    My blog - http://www.cadavre.co.uk/
    For better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/
    For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Wow.. thats somthing i dont get it..

    i might go with inline..

    so how do i set the

    and rh.CREATED_DATE between @StartDate and @endDate in the same inline query ?

  • What about using Jeff Moden's Tally table to parse the comma-delimited @Stores parameter. Store the parsed values into a temp table to directly join to the dbo.Stores table.

    DISCLAIMER: The sample below uses the "Tally" table. But, if you do not have one you can also do an inline tally. You can just search for Tally and you will see a lot of examples and forum posts on it.

    Here is one article: http://www.sqlservercentral.com/articles/Tally+Table/72993/

    --Declare and set your "stores" variable

    DECLARE @Stores AS VARCHAR(2000)

    SET @Stores = '325,785,5698';

    -- add preceeding and succeeding delimiters (i.e. comma) if they do not exist

    SET @Stores = CASE WHEN LEFT(@Stores,1)=',' THEN '' ELSE ',' END + @Stores + CASE WHEN RIGHT(@Stores,1)=',' THEN '' ELSE ',' END;

    create table #storeNbrFromParam (STORE_ID int);

    -- extract the store numbers into individual items

    -- !!!! this assumes you have a tally table !!!!!

    insert into #storeNbrFromParam (STORE_ID )

    select SUBSTRING(@Stores, t.N+1, CHARINDEX(',', @Stores, t.N+1)-t.N-1) as StoreNbr

    from master.[dbo].[Tally] t

    where t.N < LEN(@Stores)

    AND SUBSTRING(@Stores,t.N,1) = ','

    ;

    --pseudo

    select rh.*

    from dbo.Stores rh join #storeNbrFromParam snfp on snfp.STORE_ID = rh.STORE_ID

  • John Michael Robertson (11/4/2011)


    What about using Jeff Moden's Tally table to parse the comma-delimited @Stores parameter. Store the parsed values into a temp table to directly join to the dbo.Stores table.

    DISCLAIMER: The sample below uses the "Tally" table. But, if you do not have one you can also do an inline tally. You can just search for Tally and you will see a lot of examples and forum posts on it.

    Here is one article: http://www.sqlservercentral.com/articles/Tally+Table/72993/

    --Declare and set your "stores" variable

    DECLARE @Stores AS VARCHAR(2000)

    SET @Stores = '325,785,5698';

    -- add preceeding and succeeding delimiters (i.e. comma) if they do not exist

    SET @Stores = CASE WHEN LEFT(@Stores,1)=',' THEN '' ELSE ',' END + @Stores + CASE WHEN RIGHT(@Stores,1)=',' THEN '' ELSE ',' END;

    create table #storeNbrFromParam (STORE_ID int);

    -- extract the store numbers into individual items

    -- !!!! this assumes you have a tally table !!!!!

    insert into #storeNbrFromParam (STORE_ID )

    select SUBSTRING(@Stores, t.N+1, CHARINDEX(',', @Stores, t.N+1)-t.N-1) as StoreNbr

    from master.[dbo].[Tally] t

    where t.N < LEN(@Stores)

    AND SUBSTRING(@Stores,t.N,1) = ','

    ;

    --pseudo

    select rh.*

    from dbo.Stores rh join #storeNbrFromParam snfp on snfp.STORE_ID = rh.STORE_ID

    This is definitely the right direction. Read further along in the article you link about parsing strings. You will find a function called DelimitedSplit8K. It is exactly what you need for this. No complicated sql outside of the function. You just join to it and off you go.

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • Cadavre (11/4/2011)


    whole (11/4/2011)


    Hi, i have one of the parameter of my procedure as @Stores as varchar(2000) = null,

    which gets values like 325,785,5698 as inputs..

    now i need to query it against STORES table of STORE_ID (which is INT)

    i am doinf like and rh.STORE_ID in (@Stores)

    which is failing and giving me Conversion failed when converting the varchar value '325,785,5698' to data type int. error..

    could you please help me how to solve this...

    I think this is what you're after -

    --Standard TestEnvironment of 1,000,000 rows of random-ish data

    IF object_id('tempdb..#testEnvironment') IS NOT NULL

    BEGIN

    DROP TABLE #testEnvironment

    END

    --1,000,000 Random rows of data

    SELECT TOP 1000000 IDENTITY(INT,1,1) AS ID,

    RAND(CHECKSUM(NEWID())) * 30000 + CAST('1945' AS DATETIME) AS randomDate,

    ABS(CHECKSUM(NEWID())) AS randomBigInt,

    (ABS(CHECKSUM(NEWID())) % 10000) + 1 AS randomMediumInt,

    (ABS(CHECKSUM(NEWID())) % 100) + 1 AS randomSmallInt,

    RAND(CHECKSUM(NEWID())) * 100 AS randomSmallDec,

    RAND(CHECKSUM(NEWID())) AS randomTinyDec,

    RAND(CHECKSUM(NEWID())) * 100000 AS randomBigDec,

    CONVERT(VARCHAR(6),CONVERT(MONEY,RAND(CHECKSUM(NEWID())) * 100),0) AS randomMoney

    INTO #testEnvironment

    FROM master.dbo.syscolumns sc1, master.dbo.syscolumns sc2, master.dbo.syscolumns sc3

    --Declare and set your "stores" variable

    DECLARE @Stores AS VARCHAR(2000)

    SET @Stores = '325,785,5698'

    --Build query

    DECLARE @query AS VARCHAR(MAX)

    SET @query = 'SELECT * FROM #testEnvironment

    WHERE randomMediumInt IN ('+@Stores+')'

    --Execute query

    EXEC(@query)

    Be VERY careful if you use this type of approach. Make sure you read up on sql injection because this is very vulnerable.

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • Here is the query using Jeff's splitter.

    declare @Stores varchar(2000)

    set @Stores = '325,785,5698'

    --create test data

    ;with Stores(StoreID, StoreName)

    as (

    select 1, 'some store' union all

    select 325, 'Should be found' union all

    select 785, 'also found' union all

    select 434, 'Not found' union all

    select 6868, 'nope' union all

    select 5698, 'last one to find'

    )

    --here is the actual sored proc body now

    select * from Stores

    join dbo.DelimitedSplit8K(@Stores, ',') s on Stores.StoreID = s.Item

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • Cadavre (11/4/2011)


    Another method: -

    --Standard TestEnvironment of 1,000,000 rows of random-ish data

    IF object_id('tempdb..#testEnvironment') IS NOT NULL

    BEGIN

    DROP TABLE #testEnvironment

    END

    --1,000,000 Random rows of data

    SELECT TOP 1000000 IDENTITY(INT,1,1) AS ID,

    RAND(CHECKSUM(NEWID())) * 30000 + CAST('1945' AS DATETIME) AS randomDate,

    ABS(CHECKSUM(NEWID())) AS randomBigInt,

    (ABS(CHECKSUM(NEWID())) % 10000) + 1 AS randomMediumInt,

    (ABS(CHECKSUM(NEWID())) % 100) + 1 AS randomSmallInt,

    RAND(CHECKSUM(NEWID())) * 100 AS randomSmallDec,

    RAND(CHECKSUM(NEWID())) AS randomTinyDec,

    RAND(CHECKSUM(NEWID())) * 100000 AS randomBigDec,

    CONVERT(VARCHAR(6),CONVERT(MONEY,RAND(CHECKSUM(NEWID())) * 100),0) AS randomMoney

    INTO #testEnvironment

    FROM master.dbo.syscolumns sc1, master.dbo.syscolumns sc2, master.dbo.syscolumns sc3

    --Declare and set your "stores" variable

    DECLARE @Stores AS VARCHAR(2000)

    SET @Stores = '325,785,5698';

    --Query

    WITH Pieces(pn, start, stop) AS (

    SELECT 1, 1, CHARINDEX(',', @Stores)

    UNION ALL

    SELECT pn + 1, stop + 1, CHARINDEX(',', @Stores, stop + 1)

    FROM Pieces

    WHERE stop > 0)

    SELECT *

    FROM #testEnvironment

    WHERE randomMediumInt IN (SELECT SUBSTRING(@Stores, start, CASE WHEN stop > 0 THEN stop-start ELSE 2000 END) AS stores

    FROM Pieces)

    Oh, be careful now. You're asking for a snootfull of resource usage because you're using a recursive CTE to count. Even small numbers take a very large toll very quickly. Please see the following article for why you shouldn't use recursive CTE's for such a thing.

    http://www.sqlservercentral.com/articles/T-SQL/74118/

    Instead of resorting to the temptation of using an rCTE for such a thing, use a good splitter instead. There's one in the "resources" links at the bottom of the following article...

    http://www.sqlservercentral.com/articles/Tally+Table/72993/

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • hi I found this function somewhere on web and it have been very helpful 🙂

    just run it on your DB and you can always reference it from anywhere

    /*

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    CREATE FUNCTION [dbo].[fn_Split]

    (

    @RowData NVARCHAR(MAX),

    @Delimeter NVARCHAR(MAX)

    )

    RETURNS @RtnValue TABLE

    (

    ID INT IDENTITY(1,1),

    Data NVARCHAR(MAX)

    )

    AS

    BEGIN

    DECLARE @Iterator INT

    SET @Iterator = 1

    DECLARE @FoundIndex INT

    SET @FoundIndex = CHARINDEX(@Delimeter,@RowData)

    WHILE (@FoundIndex>0)

    BEGIN

    INSERT INTO @RtnValue (data)

    SELECT

    Data = LTRIM(RTRIM(SUBSTRING(@RowData, 1, @FoundIndex - 1)))

    SET @RowData = SUBSTRING(@RowData,

    @FoundIndex + DATALENGTH(@Delimeter) / 2,

    LEN(@RowData))

    SET @Iterator = @Iterator + 1

    SET @FoundIndex = CHARINDEX(@Delimeter, @RowData)

    END

    INSERT INTO @RtnValue (Data)

    SELECT Data = LTRIM(RTRIM(@RowData))

    RETURN

    END

    */

  • ryvlad (11/7/2011)


    hi I found this function somewhere on web and it have been very helpful 🙂

    just run it on your DB and you can always reference it from anywhere

    You should look at the article by Jeff that I linked several posts ago. Or you can find it in my signature. A loop is not the best approach for splitting strings. It is slow and inefficient. Read that article and look at the performance differences he discusses. He talks about a number of ways of splitting strings and other than parsing xml that type of splitter is the worst performer of them all.

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • will do , thanks

  • Hey Sean, does Jeff send you some sort of royalty checks in the mail from time-to-time? 😉

    (heh, heh)

    ______________________________________________________________________________Never argue with an idiot; Theyll drag you down to their level and beat you with experience

Viewing 15 posts - 1 through 15 (of 22 total)

You must be logged in to reply to this topic. Login to reply