Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

t-sql Convert comma separated string into int, without using user created function

Tags:

tsql

I'm passing a list of int's (comma separated)

ie. 1, 2, 3, 4

to my sp. But I'm getting an error because the list is a string, and I'm comparing to an int field. Is there a way for me to convert the list to int, without using a user created function?

Note: employeeID is INT

declare @intArray varchar(200)

SELECT *
FROM tbl_Employee
WHERE employeeID IN ( @intArray )

The error is "Cannot convert type varchar to int"

like image 353
Since_2008 Avatar asked Dec 17 '10 14:12

Since_2008


People also ask

How do I CAST a comma separated value in SQL?

DECLARE @xml AS XML, @str AS VARCHAR(100), @delimiter AS VARCHAR(10); SET @str = '12345,87612,988473'; SET @delimiter = ','; SET @xml = CAST('<X>' + REPLACE(@str, @delimiter, '</X><X>') + '</X>' AS XML); SELECT [N]. value( '. ', 'varchar(50)' ) AS value FROM @xml. nodes( 'X' ) AS [T]( [N] );

How remove comma separated values in SQL query?

You will need a string splitter to first separate the values into something usable. Then you will need to use STUFF and FOR XML to smash them back together into this denormalized nightmare. Use a nested replace. The innermost is , 15, .

What is CAST () and convert () functions in SQL Server?

The cast and convert functions provide similar functionality. They are used to convert a value from one data type to another. So let's take a look at a practical example. The example is developed in SQL Server 2012 using the SQL Server Management Studio.


Video Answer


3 Answers

If you are using sql server 2016 and above then use STRING_SPLIT

declare @intArray varchar(200)
Set @intArray = '3,4,6,7'

SELECT *
FROM tbl_Employee
WHERE employeeID IN (select * from STRING_SPLIT(@intArray, ','))
like image 130
Manish Kumar Avatar answered Oct 16 '22 23:10

Manish Kumar


You don't want to cast that list into an int, but into a list of ints.

There is no cast operator or function for that, but you can use dynamic SQL to get around it.

Basically you write

EXECUTE('SELECT * FROM tbl_Employee WHERE employeeID IN ('+@intArray+')')

Be aware of SQL injection attacks though!

like image 20
TToni Avatar answered Oct 16 '22 21:10

TToni


You're trying to convert not only a string to int, but several ints into one. Do you expect that your SELECT will return all employee's with and ID listed in the array?

I realize that you wanted to do this without a function. However, this is how I currently do it and it works great. Take what you will from my answer.

This code uses a while loop which could likely be improved to a recursive CTE if you are in SQL 2005/2008. You can use the output of the function as a table that you INNER JOIN to which will allow you to filter very quickly.

/*
************************************************************************************************************************
    Name:           ConvertDelimitedListIntoTable
    Description:    Converts a list of delimited values into a table for use like a dynamic IN statment

    Modification History
    Date        Author          Description
    ==========  ============    ====================================
    2009-01-31  B. Williams     Initial Creation

************************************************************************************************************************
*/
ALTER FUNCTION [dbo].[ConvertDelimitedListIntoTable] (
     @list NVARCHAR(MAX) ,@delimiter CHAR(1) )
RETURNS @table TABLE ( 
     item VARCHAR(255) NOT NULL )
AS 
    BEGIN
        DECLARE @pos INT ,@nextpos INT ,@valuelen INT

        SELECT  @pos = 0 ,@nextpos = 1

        WHILE @nextpos > 0 
            BEGIN
                SELECT  @nextpos = CHARINDEX(@delimiter,@list,@pos + 1)
                SELECT  @valuelen = CASE WHEN @nextpos > 0 THEN @nextpos
                                         ELSE LEN(@list) + 1
                                    END - @pos - 1
                INSERT  @table ( item )
                VALUES  ( CONVERT(INT,SUBSTRING(@list,@pos + 1,@valuelen)) )
                SELECT  @pos = @nextpos

            END

        DELETE  FROM @table
        WHERE   item = ''

        RETURN 
    END

Use:

DECLARE @intArray varchar(200)

SELECT *
FROM  tbl_Employee e
      INNER JOIN dbo.ConvertDelimitedListIntoTable(@intArray,',') arr
                 ON e.EmployeeID = arr.Item

There may also be a quick way to do this with a tally table.

like image 21
Brad Avatar answered Oct 16 '22 22:10

Brad