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

Cách chuyển một mảng vào một thủ tục được lưu trữ trên SQL Server

SQL Server 2008 (hoặc mới hơn)

Đầu tiên, trong cơ sở dữ liệu của bạn, hãy tạo hai đối tượng sau:

CREATE TYPE dbo.IDList
AS TABLE
(
  ID INT
);
GO

CREATE PROCEDURE dbo.DoSomethingWithEmployees
  @List AS dbo.IDList READONLY
AS
BEGIN
  SET NOCOUNT ON;

  SELECT ID FROM @List; 
END
GO

Bây giờ trong mã C # của bạn:

// Obtain your list of ids to send, this is just an example call to a helper utility function
int[] employeeIds = GetEmployeeIds();

DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("ID", typeof(int)));

// populate DataTable from your List here
foreach(var id in employeeIds)
    tvp.Rows.Add(id);

using (conn)
{
    SqlCommand cmd = new SqlCommand("dbo.DoSomethingWithEmployees", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter tvparam = cmd.Parameters.AddWithValue("@List", tvp);
    // these next lines are important to map the C# DataTable object to the correct SQL User Defined Type
    tvparam.SqlDbType = SqlDbType.Structured;
    tvparam.TypeName = "dbo.IDList";
    // execute query, consume results, etc. here
}

SQL Server 2005

Nếu bạn đang sử dụng SQL Server 2005, tôi vẫn khuyên bạn nên sử dụng hàm phân tách qua XML. Đầu tiên, hãy tạo một hàm:

CREATE FUNCTION dbo.SplitInts
(
   @List      VARCHAR(MAX),
   @Delimiter VARCHAR(255)
)
RETURNS TABLE
AS
  RETURN ( SELECT Item = CONVERT(INT, Item) FROM
      ( SELECT Item = x.i.value('(./text())[1]', 'varchar(max)')
        FROM ( SELECT [XML] = CONVERT(XML, '<i>'
        + REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
          ) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y
      WHERE Item IS NOT NULL
  );
GO

Bây giờ thủ tục được lưu trữ của bạn chỉ có thể là:

CREATE PROCEDURE dbo.DoSomethingWithEmployees
  @List VARCHAR(MAX)
AS
BEGIN
  SET NOCOUNT ON;

  SELECT EmployeeID = Item FROM dbo.SplitInts(@List, ','); 
END
GO

Và trong mã C # của bạn, bạn chỉ cần chuyển danh sách dưới dạng '1,2,3,12' ...

Tôi nhận thấy phương pháp chuyển qua các tham số có giá trị trong bảng đơn giản hóa khả năng bảo trì của một giải pháp sử dụng nó và thường tăng hiệu suất so với các cách triển khai khác bao gồm cả XML và phân tách chuỗi.

Các đầu vào được xác định rõ ràng (không ai phải đoán xem dấu phân cách là dấu phẩy hay dấu chấm phẩy) và chúng tôi không có sự phụ thuộc vào các hàm xử lý khác không rõ ràng nếu không kiểm tra mã cho thủ tục được lưu trữ.

So với các giải pháp liên quan đến lược đồ XML do người dùng xác định thay vì UDT, điều này liên quan đến một số bước tương tự nhưng theo kinh nghiệm của tôi là mã đơn giản hơn nhiều để quản lý, duy trì và đọc.

Trong nhiều giải pháp, bạn có thể chỉ cần một hoặc một vài UDT (Loại do người dùng xác định) mà bạn sử dụng lại cho nhiều thủ tục được lưu trữ. Như với ví dụ này, yêu cầu chung là chuyển qua danh sách các con trỏ ID, tên hàm mô tả ngữ cảnh mà các Id đó sẽ đại diện, tên kiểu phải là chung chung.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hành vi @@ rowcount không mong muốn bên trong UDF trong MS SQL 2019

  2. Sử dụng FILEGROUP_NAME () để trả lại tên của nhóm tệp trong SQL Server

  3. Cách sử dụng RANK () trong SQL Server

  4. SQL Chọn sinh nhật sắp tới

  5. Ba xu hướng hàng đầu ảnh hưởng đến các DBA chịu trách nhiệm giám sát máy chủ SQL