This could be a duplicate, but I can't find any answers to similar questions that suggest a table valued parameter for the stored procedure which could be a viable solution, and removes the need for dynamic SQL and the risk of SQL injection (not all hacks are associated with this risk). Table valued parameters should also offer better performance as the execution plan can be stored, rather than dynamic solution where the plan must be created on the fly.
CREATE TYPE dbo.AttCodeTableType AS TABLE (AttCode VARCHAR(MAX))
GO
CREATE PROCEDURE PEX_SP_ActivityException_Select (@startDate DATE, @EndDate DATE, @AttCodes dbo.AttCodeTableType READONLY)
AS
BEGIN
SELECT e.EmployeeID, e.Badge, e.LastName, e.FirstName, a.Date, ac.Code
FROM Employee e
INNER JOIN Attendance a
ON a.FKEmployee = e.EmployeeID
INNER JOIN AttendanceCodes ac
ON ac.AttendanceCodesID = a.FKAttendanceCode
INNER JOIN @AttCodes act
ON act.AttCode = ac.Code
WHERE a.Date BETWEEN @StartDate AND @EndDate
END
GO
Then to execute the procedure you can use something like:
DECLARE @Table AS dbo.AttCodeTableType
INSERT @Table VALUES ('Code1'), ('Code2'), ('Code3')
EXEC PEX_SP_ActivityException_Select @Table
To create an SQL parameter from a datatable in vb.net you would use something like the following:
dim sqlParam as new SqlParameter("@Table", DataTable)
sqlParam.SqlDbType = SqlDbType.Structured
sqlParam.TypeName = "dbo.AttCodeTableType"
Read here for more info.
Finally, WORK ON YOUR ACCEPT RATE!!!