A: 

Not sure if this is the best solution, but I believe you can batch multiple commands by wrapping them in a BEGIN/END block, and use a single call to run all of them.

Badaro
er.. not really
gbn
+3  A: 

Use a temporary table which persists for the duration of the session/connection (multiple calls). Table variables have scope only for the batch, which is basically one call.

gbn
+1, table @variables are slower than #temp tables when you insert many rows, like the question says is going to happen
KM
Would it really be slower than performing disc I/O to a temp-table, which also bothers the transaction log? I'm considering that the table variable is only one column (I could make it varchar rather than char) and the size of the table may be relatively small. The total length of all usernames is currently 32370 characters. I am currently using a temp table, because I just had to change the '@' to a '#' to make it work, lol, but I'm still curious about how to deal with a variable persisting across SqlCommand calls without error.
Triynko
I don't think you can. You also have to consider the performance when reading from the table variable. SQL keeps no stats and always assumed one row. You'd save on load but lose on later read.
gbn
A: 

I dont know how to solve your question, however my alternative approach to your problem would instead be to have a stored procedure that accepted a comma delimited list of ID's, inserted those ID's into a temporary table and then do a "SELECT WHERE IN", for example (altered from another blog):

CREATE PROC dbo.SelectStudents
(
    @StudentIdList varchar(8000)
)
AS
BEGIN
    SET NOCOUNT ON

    CREATE TABLE #StudentIdList (
     StudentId int,
    )

    DECLARE @StudentId varchar(10), @Pos int

    SET @StudentIdList = LTRIM(RTRIM(@StudentIdList)) + ','
    SET @Pos = CHARINDEX(',', @StudentIdList, 1)

    IF REPLACE(@StudentIdList, ',', '') <> ''
    BEGIN
     WHILE @Pos > 0
     BEGIN
      SET @StudentId = LTRIM(RTRIM(LEFT(@StudentIdList, @Pos - 1)))
      IF @StudentId <> ''
      BEGIN
       INSERT INTO #StudentIdList (StudentId) VALUES (CAST(@StudentId AS int))
      END
      SET @StudentIdList = RIGHT(@StudentIdList, LEN(@StudentIdList) - @Pos)
      SET @Pos = CHARINDEX(',', @StudentIdList, 1)
     END
    END 

    SELECT  * 
    FROM  dbo.Students
    WHERE StudentId IN
    (
     SELECT StudentId FROM #StudentIdList
    )
END

You can then call this stored procedure with a comma delimtied list of id's:

exec dbo.SelectStudents '1,2'

You will need to make sure that your formatted list of id's is no longer than 8000 characters (and make multiple calls to the database if it is) however this method will be far more efficient and requires only a large parameter, not a long command text - making large numbers of trips to the database to insert each of the Id's will be extremely slow.

Similar approaches exist for passing in the list of Id's as Xml (although my preference would probably be to go for the simplicity of delimited strings).

Also, it shoud be possible to use the above technique even if for whatever reason you aren't able to create stored procedures on your database.

Kragen
sql 2005+ supports n/varchar(max)
devio
that is a slow way to split strings, there are much better ways: http://www.sommarskog.se/arrays-in-sql.html
KM
"Assume creating stored procedures is not an option." Yeah, I don't want to concatenate 10,000 usernames, only to split them again in a T-SQL stored procedure. The total character length of all usernames is already 32370, which is definitely more than 8000, and is likely to quadruple by September.
Triynko
String manipulation is cheap, however round trips to the database and back are not! Not to mention that doing the inserts into the temporary table individually outside of a transaction prevents lock escalation which will have a large impact on performance.
Kragen
+1  A: 

What's wrong with lengthy command texts? I've executed several kilobyte big query's in one call. SQL2005 supports it, and I think it's better than round-tripping all the time.

Why not create the query like this?

select StudentID, FName, LName, [etc.] from Student 
where StudentID in ('bob000001', 'bob000002', [etc.])
fretje
First of all, building up this request (by concatenating together string values) is prone to SQL injection. Also, if you call it repeatedly with different values, it's a different query every time, so SQL Server needs to find out a query plan every time. Using parameters allows SQL Server to create a query plan ONCE and then reuse that plan over and over again --> MUCH better for performance!
marc_s
Yes, you're right, but concerning that you have all the information you need in the link provided in another answer below (by AlexK)
fretje
That is more concise than using where clauses, but suffers the same problems: a new query plan generated every time, and lots of string concatenation.
Triynko
+1  A: 

Erland's article should address your issues:

http://www.sommarskog.se/arrays-in-sql-2005.html

AlexKuznetsov