Home Forums SQL Server 2008 SQL Server 2008 - General Passing comma separated values for IN list in DELETE statement from SQLCMD RE: Passing comma separated values for IN list in DELETE statement from SQLCMD

  • LANdango.com (11/9/2012)


    The anwers above are pretty good; however, there's a short cut. use XML. In just a few lines you can get what you want and the performance is really nice. Using this approach eliminates the need for round-trips to the server. (Think how fast this would be by flagging data grid rows, collecting the IDs into a string and then calling a procedure one time to delete all the selected records in just one call! Heck, you could return the table of ids from a table valued function. Have fun with it!

    declare @xml xml

    set @xml = N'<root><r>' + replace(replace(@CommaSeparatedListOfIds,',','</r><r>'),' ', '') + '</r></root>'

    Delete from MyTable

    where ID IN (

    select r.value('.','nvarchar(max)') as item

    from @xml.nodes('//root/r') as records(r))

    DONE! :w00t:

    Here's a working sample:

    Create proc DeleteStories(@CommaSeparatedListOfIds NVARCHAR(MAX))

    AS

    BEGIN

    /*11/09/2012::Created by M.M.(www.reinid.com / http://www.nmtcr.com)

    Purpose: Deletes a records by rows

    Sample execution:

    exec DeleteStories '1,2,3,4,10,100,1000,1001,2001'

    */

    /*Next section is not really needed if the input is clean

    set @CommaSeparatedListOfIds = replace(@CommaSeparatedListOfIds, ',,',',') --just in case doubles come in

    --Ensure that there are no trailing commas in input

    while(right(@CommaSeparatedListOfIds,1) = ',')

    begin

    set @CommaSeparatedListOfIds = LEFT(@CommaSeparatedListOfIds,len(@CommaSeparatedListOfIds)-1)

    end

    */

    --Here's the real "magic"

    --Create an XML document that will be used to extract the IDs from the string input

    declare @xml xml

    set @xml = N'<root><r>' + replace(replace(@CommaSeparatedListOfIds,',','</r><r>'),' ', '') + '</r></root>'

    --Display the values

    select r.value('.','nvarchar(max)') as item from @xml.nodes('//root/r') as records(r)

    --Or use the r.value in an IN statement

    /*

    Delete from StoriesTable where StoryId IN (select r.value('.','nvarchar(max)') as item from @xml.nodes('//root/r') as records(r))

    */

    END

    You should read the article referenced repeatedly. In case you missed it you can find it in my signature about splitting strings. The XML type of splitter you posted is not only discussed but performance tested in that article. It is way faster than this type of XML splitting.

    Using this approach eliminates the need for round-trips to the server. (Think how fast this would be by flagging data grid rows, collecting the IDs into a string and then calling a procedure one time to delete all the selected records in just one call! Heck, you could return the table of ids from a table valued function.

    This is EXACTLY what the Delimited Splitter does. Returns the data from a table valued function. The scenario you describe is the entire reason it was created. There is nothing inherently wrong with the XML splitter but the other version will beat on performance. 🙂

    _______________________________________________________________

    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/