2011-09-18 71 views
13

Tôi đã lưu thủ tục mà tôi phải chuyển tham số, Nhưng vấn đề là tôi không biết chắc có bao nhiêu tham số sẽ đến 1, trong lần chạy tiếp theo có thể là 5.thủ tục lưu sẵn với số tham số khác nhau

cmd.Parameters.Add(new SqlParameter("@id", id) 

Bất kỳ ai có thể giúp tôi có thể chuyển số tham số biến này trong quy trình được lưu trữ không? Cảm ơn

+1

Để vượt qua một số thay đổi các thông số, bạn sẽ chỉ có logic có điều kiện trong mã khách hàng của bạn để thêm các thông số cần thiết nhưng bạn có nghĩa là bạn muốn biết làm thế nào để vượt qua một số khác nhau của 'id' để proc được lưu trữ? –

+0

có ... thứ gì đó của nó giống như truyền mảng tới quy trình được lưu trữ ... nhưng độ dài của mảng này có thể thay đổi. – CPDS

+0

RDBMS là gì cho (bao gồm cả phiên bản)? –

Trả lời

13

Bạn có thể chuyển giá trị đó dưới dạng danh sách được phân cách bằng dấu phẩy, sau đó sử dụng chức năng tách và tham gia vào kết quả.

CREATE FUNCTION dbo.SplitInts 
(
    @List  VARCHAR(MAX), 
    @Delimiter CHAR(1) 
) 
RETURNS TABLE 
AS 
    RETURN 
    (
     SELECT Item = CONVERT(INT, Item) 
     FROM 
     (
      SELECT Item = x.i.value('(./text())[1]', 'INT') 
      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 
    ); 

Bây giờ thủ tục lưu trữ của bạn:

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

    SELECT cols FROM dbo.table AS t 
     INNER JOIN dbo.SplitInts(@List, ',') AS list 
     ON t.ID = list.Item; 
END 
GO 

Sau đó, để gọi nó là:

EXEC dbo.doStuff @List = '1, 2, 3, ...'; 

Bạn có thể thấy một số nền tảng, lựa chọn khác, và so sánh hiệu suất ở đây:

Tất nhiên, nếu bạn đang sử dụng SQL Server 2008 hoặc cao hơn, bạn có thể vượt qua những trong việc sử dụng hiệu quả hơn nhiều thông số bảng giá trị (TVPs). Xem ở đây để giới thiệu nhanh:

5

SQLServer cho phép bạn chuyển thông số TABLE đến quy trình được lưu trữ. Vì vậy, bạn có thể xác định loại bảng, CREATE TYPE LIST_OF_IDS AS TABLE (id int not null primary key), thay đổi thủ tục của bạn để chấp nhận một biến loại này (nó phải là chỉ đọc).

2

Bạn có cân nhắc sử dụng dictionary cho mục đích đó không? Nó sẽ cho phép bạn chuyển bất kỳ số tham số nào làm cặp khóa-giá trị. Sau đó, bạn sẽ cần phải đi qua từ điển và thêm các tham số đó vào cmd.

void DoStuff(Dictionary<string, object> parameters) 
{ 
    // some code 
    foreach(var param in parameters) 
    { 
     cmd.Parameters.Add(new SqlParameter(param.Key, param.Value); 
    } 
    // some code 
} 

Trong thủ tục được lưu trữ, bạn sẽ cần chỉ định giá trị mặc định cho tham số.

CREATE PROCEDURE DoStuff(
    @id INT = NULL, 
    @value INT = NULL, 
    -- the list of parameters with their default values goes here 
    ) 
AS 
-- procedure body 
+0

Đây là bên C# ... Làm thế nào để tôi đọc điều này trên máy chủ sql bên ... làm thế nào tôi tạo thủ tục? – CPDS

+0

Bạn có thể kiểm tra phản ứng của Andomar đối với mẫu quy trình. Chỉ cần thêm đoạn mã tương tự để có mọi thứ ở cùng một nơi. – Li0liQ

6

Quy trình được lưu trữ hỗ trợ các thông số tùy chọn. Giống như C# 4, bạn có thể chỉ định một giá trị mặc định bằng cách sử dụng =. Ví dụ:

create procedure dbo.doStuff(
    @stuffId int = null, 
    @stuffSubId int = null, 
    ...) 
as 
... 

Đối với các thông số bạn không muốn vượt qua, hoặc đặt chúng vào null hoặc không thêm chúng vào cmd.Parameters ở tất cả. Họ sẽ có giá trị mặc định của họ trong thủ tục được lưu trữ

Các vấn đề liên quan