예, 사용 테이블 반환 매개 변수를 사용하고 있습니다. A의 통과 것이다
CREATE PROCEDURE dbo.MarkStudentsAsDeleted
@IDs dbo.StudentIDs READONLY
AS
BEGIN
SET NOCOUNT ON;
UPDATE s SET IsDeleted = 1
FROM dbo.Students AS s
INNER JOIN dbo.Class AS c
ON s.StudentId = c.StudentId
INNER JOIN dbo.ClassValueTable AS ct
ON c.PassId = ct.Id
WHERE ct.IsDeleted <> 1
AND EXISTS (SELECT 1 FROM @IDs WHERE StudentID = s.StudentID);
END
GO
그리고 당신의 C# 코드 :
는
CREATE TYPE dbo.StudentIDs(ID INT PRIMARY KEY);
이제 절차 (가입 나는 적절한에 중첩 된 IN
쿼리를 변경 한 주)를 사용할 수있다 : 첫째 유형을 만들 DataTable 또는 쉼표로 구분 된 목록이 아닌 activeId 컬렉션을 어셈블했습니다.
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Rows.Add(1);
dt.Rows.Add(2);
dt.Rows.Add(3);
dt.Rows.Add(4);
... open connection etc. ...
SqlCommand cmd = new SqlCommand("dbo.MarkStudentsAsDeleted", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvp1 = cmd.Parameters.AddWithValue("@IDs", dt);
tvp1.SqlDbType = SqlDbType.Structured;
cmd.ExecuteNonQuery();
... close, dispose, etc. ...
문자열을 저장 프로 시저에 전달하려는 경우 분리 함수를 사용해야합니다. 예를 들어 :
CREATE FUNCTION dbo.SplitInts
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(255) = ','
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT [value] = y.i.value('(./text())[1]', 'int')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
GO
이제 저장 프로 시저가 될 수 있습니다
CREATE PROCEDURE dbo.MarkStudentsAsDeleted
@IDs VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
UPDATE s SET IsDeleted = 1
FROM dbo.Students AS s
INNER JOIN dbo.Class AS c
ON s.StudentId = c.StudentId
INNER JOIN dbo.ClassValueTable AS ct
ON c.PassId = ct.Id
WHERE ct.IsDeleted <> 1
AND EXISTS (SELECT 1 FROM dbo.SplitInts(@IDs, ',') WHERE Item = s.StudentID);
END
GO
[테이블 반환 매개 변수 (http://msdn.microsoft.com/en-us/library/bb675163.aspx) (그러나 C# 3이'SqlDbType.Structured'를 알고 있는지 모르겠다.) –
@TimSchmelter - activeIds는 문자열이다. 그냥 문자열로 넘겨 줘? – NoviceMe
테이블 반환 매개 변수를 사용하지 않고 사용하십시오. 왜 그것은 문자열이어야합니까? 어떤 시점에서 컬렉션에서 나오지 않습니까? 왜 그것을 문자열로 변환해야 비 문자열로 나눌 수 있습니까? 만약 당신이 그렇게하려고한다면, 지금 사용하고있는 SQL injection haven을 계속 사용하십시오 ... –