Nov*_*eMe 1 sql-server-2008 c#-3.0
我有以下查询:
@"UPDATE students SET IsDeleted = 1 WHERE StudentId IN (
SELECT StudentId FROM Class where PassId IN (
SELECT Id FROM ClassValueTable WHERE IsDeleted <> 1"
+ activeIds)))";
Run Code Online (Sandbox Code Playgroud)
其中activeIds =一些数字的字符串,例如:1,2,3,4 ...
我想将此查询转换为存储过程。我的问题是将activeIds作为参数传递给此存储过程的最佳方法是什么?
*代码在C#中并且正在使用SQL Server 2008
是的,使用表值参数。首先创建一个类型:
CREATE TYPE dbo.StudentIDs(ID INT PRIMARY KEY);
Run Code Online (Sandbox Code Playgroud)
现在您的过程可以使用此方法(请注意,我已将嵌套IN查询更改为适当的联接):
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
Run Code Online (Sandbox Code Playgroud)
您的C#代码将传递到DataTable中,或者您组装了activeIds的集合,而不是用逗号分隔的列表。
CREATE TYPE dbo.StudentIDs(ID INT PRIMARY KEY);
Run Code Online (Sandbox Code Playgroud)
如果要坚持将字符串传递到存储过程中,则需要使用split函数。例如:
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
Run Code Online (Sandbox Code Playgroud)
现在您的存储过程可以是:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2253 次 |
| 最近记录: |