Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Các tham số giá trị bảng có nên được sử dụng ở đây không?

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để xóa (ngăn chặn SQL injection) động SQL trong SQL Server?

  2. Hiệu suất SQL-Server:Nhanh hơn, một thủ tục được lưu trữ hay một dạng xem?

  3. Cách cài đặt sqlcmd &bcp trên Ubuntu

  4. Các quy tắc sử dụng Tham số nội bộ trong SSRS là gì

  5. Làm cách nào để cho phép tham số danh sách thả xuống trong SSRS có giá trị mặc định là - Tất cả -?