2009-06-10 6 views
6

Tôi muốn chạy một truy vấn như thế này:Quy trình được lưu trữ có tham số động được sử dụng trong mệnh đề "IN" không?

SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566) 

nhưng lượng Id 's truyền cho mệnh đề IN được chỉ định khi chạy.

Tôi có phải sử dụng SQL động hay điều này có thể được thực hiện bằng quy trình được lưu trữ không?

CẬP NHẬT: Nếu có một tùy chọn nào, tùy chọn nào khả dụng hơn?

Cảm ơn.

+0

là id của tạo ra bởi người sử dụng đầu vào? – Eric

+0

Người dùng chọn các bản ghi để tìm kiếm bằng một hộp kiểm nhưng họ không có quyền kiểm soát đối với "Id" thực tế là gì. – orandov

+0

Sau đó, sql động không phải là một ý tưởng tồi nếu nó không phải chịu tiêm ... nhưng hãy thử câu trả lời tôi được đăng để an toàn. – Eric

Trả lời

8

Tùy thuộc vào phiên bản của SQL Server, bạn có thể làm điều này theo một trong hai cách khác nhau.

Đối với Sql 2000/2005, bạn có thể sử dụng tham số (loại varchar) có danh sách ID phân tách. Tạo một UDF để phân tích vec tơ và trả về một bảng chứa các mục. Sau đó, đặt mệnh đề IN của bạn đi ngược lại bảng (tức là ... IN (Chọn ID FROM @ReturnTable)).

Dưới đây là một ví dụ về những gì mà nội dung của UDF sẽ trông như thế: http://pietschsoft.com/post/2006/02/03/T-SQL-Parse-a-delimited-string.aspx

Đối với Sql 2008, bạn có thể làm điều tương tự; Tuy nhiên thay vì truyền vào một tham số varchar, bạn có thể chỉ cần cắt theo đuổi và chuyển vào một tham số Table. Mệnh đề IN vẫn sẽ có một truy vấn con nhưng nó sẽ hoạt động như nhau. Ngoài ra, một khi bạn có bảng, bạn chỉ có thể làm một Inner Join trên nó và phá vỡ sự cần thiết cho mệnh đề IN.

EDIT: đã thêm UDF để phân tích cú pháp liên kết chuỗi phân tách.

+0

Vì liên kết của bạn không còn hoạt động nữa, tôi sẽ chia sẻ liên kết này: http://jerrytech.blogspot.com/2008/04/no-split-in-sql-well-here-method-you .html –

0

Trong SQL 2008, bạn có thể sử dụng table valued parameter.

Trong SQL 2005, bạn phải sử dụng SQL động trừ khi bạn muốn chuyển danh sách dưới dạng XML và sử dụng xử lý XML trong thủ tục để tách XML trở lại thành một biến bảng.

+0

Bạn không cần SQL động để phân tích cú pháp danh sách phân tách. Xem trang của Erland Sommarskog, như đã đề cập bởi Alex. –

+0

Hey Remus, Tôi không đồng ý. Tôi làm việc vào năm 2005, tôi lấy các con số vào một hình ảnh và phân tích chúng bằng cách sử dụng UDF: http://www.sommarskog.se/arrays-in-sql-2005.html –

+0

đúng, tôi cho rằng việc xử lý chuỗi là một giải pháp khả thi và tôi nên đề cập đến nó. Cà phê bị tước đoạt bài viết :) –

0

khai báo bảng @temp và chia các giá trị thành nó. sau đó bạn có thể làm

select * from Studio s bên tham gia @temptable tb trên s.ID = tb.ID

3

Bạn hoàn toàn có thể làm điều này trong một thủ tục lưu trữ.

tạo một bảng tạm thời bên trong thủ tục lưu trữ và chèn các giá trị chia trên dấu phẩy hoặc bất kỳ dấu phân cách sau đó làm điều này

SELECT * FROM Studio WHERE Id IN (select id from temptable) 

Sau đó xóa bảng.

+0

Đây có thể là giải pháp tốt nhất bởi vì bạn không bao giờ biết bao nhiêu dữ liệu stinking bạn đang đi vào thủ tục được lưu trữ đó. Bạn có thể cải thiện hiệu suất đáng kể bằng cách sử dụng bảng tạm thời như vậy nếu số lượng cao. –

1

Đây là một UDF mà tôi đã sử dụng từ MSSQL 2000. Tôi tìm thấy ở đâu đó - xin lỗi, không thể nhớ ở đâu.

Về cơ bản, bạn có thể thực hiện một phép nối trên UDF, trong đó tham số đầu tiên là chuỗi phân cách và tham số thứ hai là dấu phân tách.

CHỌN t1.somecolumn TỪ t1 sometable INNER JOIN dbo.Split (@delimitedVar, '') t2 ON t1.ID = t2.Element

CREATE FUNCTION [dbo].[Split] 
(
@vcDelimitedString varchar(max), 
@vcDelimiter varchar(100) 
) 
RETURNS @tblArray TABLE 
    (
    ElementID smallint IDENTITY(1,1), --Array index 
    Element varchar(1000) --Array element contents 
    ) 
AS 
BEGIN 
    DECLARE @siIndex smallint, @siStart smallint, @siDelSize smallint 
    SET @siDelSize = LEN(@vcDelimiter) 
    --loop through source string and add elements to destination table array 
    WHILE LEN(@vcDelimitedString) > 0 
    BEGIN 
     SET @siIndex = CHARINDEX(@vcDelimiter, @vcDelimitedString) 
     IF @siIndex = 0 
     BEGIN 
      INSERT INTO @tblArray VALUES(@vcDelimitedString) 
      BREAK 
     END 
     ELSE 
     BEGIN 
      INSERT INTO @tblArray VALUES(SUBSTRING(@vcDelimitedString, 1,@siIndex - 1)) 
      SET @siStart = @siIndex + @siDelSize 
      SET @vcDelimitedString = SUBSTRING(@vcDelimitedString, @siStart , LEN(@vcDelimitedString) - @siStart + 1) 
     END 
    END 
    RETURN 
END