Có, sử dụng các tham số có giá trị bảng. Đầu tiên, hãy tạo một loại:
CREATE TYPE dbo.StudentIDs(ID INT PRIMARY KEY);
Bây giờ thủ tục của bạn có thể sử dụng điều này (lưu ý rằng tôi đã thay đổi IN
lồng nhau của bạn truy vấn đến một kết hợp thích hợp):
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
Và mã C # của bạn sẽ được chuyển vào DataTable hoặc tuy nhiên bạn đã tập hợp tập hợp các ActiveIds, thay vì một danh sách được phân tách bằng dấu phẩy.
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. ...
Nếu bạn muốn nhấn mạnh vào việc truyền một chuỗi vào thủ tục được lưu trữ, bạn sẽ cần phải sử dụng hàm phân tách. Ví dụ:
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
Bây giờ thủ tục được lưu trữ của bạn có thể là:
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