2012-07-26 39 views
5

Quy trình này có ba tham số. Nhưng khi tôi cố gắng thực hiện bằng cách truyền tham số, nó cho tôi thấy một lỗi. Làm ơn giúp tôi.đối số quy trình được lưu trữ sql làm tham số cho truy vấn động

create procedure queryfunctions @Tabname varchar(150),@colname varchar(150),@valuesname varchar(150) 
as 
begin 
declare @sql varchar(4000) 
select @sql='select * from @Tabname where @[email protected]' 
exec(@sql) 
end 

exec queryfunctions 'education','eduChildName','Revathi' 

Lỗi:

Msg 1087, Level 15, State 2, Line 1 Phải khai báo biến bảng "@Tabname".

+1

Bạn có thể vui lòng xác nhận rằng bạn đang tìm kiếm (các) hàng trong bảng 'giáo dục' trong đó cột' eduChildName' chứa giá trị chuỗi '' Revathi'' chứ không phải (các) hàng trong đó 'eduChildName' cột chứa cùng giá trị với cột 'Revathi'? –

+0

Tôi đã xóa câu trả lời của tôi, vì nó đã kéo quá nhiều downvotes vì ​​một lý do nào đó. Xin lỗi baji, bạn đang ở trên của riêng bạn với các câu trả lời khác mà bạn có, ngay cả khi họ không phải là như vậy hữu ích. – Guffa

Trả lời

11

Đây là một lựa chọn an toàn hơn nhiều:

ALTER PROCEDURE dbo.queryfunctions 
    @Tabname NVARCHAR(511), 
    @colname NVARCHAR(128), 
    @valuesname VARCHAR(150) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 

    SET @sql = 'SELECT * FROM ' + @Tabname 
      + ' WHERE ' + QUOTENAME(@colname) + ' = @v'; 

    EXEC sp_executesql @sql, N'@v VARCHAR(150)', @valuesname; 
END 
GO 

EXEC dbo.queryfunctions N'dbo.education', N'eduChildName', 'Revathi'; 

tôi đã thay đổi gì?

  1. Luôn sử dụng tiền tố dbo khi tạo/tham chiếu đối tượng.
  2. Tên bảng và cột là NVARCHARcó thể dài hơn 150 ký tự. An toàn hơn nhiều để cho phép các tham số chứa một bảng mà ai đó có thể thêm vào trong tương lai.
  3. Đã thêm SET NOCOUNT ON làm người bảo vệ chống lại phí trên mạng và có khả năng gửi các bộ kết quả sai tới khách hàng.
  4. @sql phải luôn là NVARCHAR.
  5. Sử dụng QUOTENAME xung quanh tên thực thể như bảng hoặc cột để giúp ngăn chặn việc tiêm SQL và cũng để bảo vệ chống lại các tên được chọn kém (ví dụ: từ khóa).
  6. Sử dụng các thông số thích hợp nếu có thể (một lần nữa để giúp ngăn chặn việc tiêm SQL nhưng cũng để tránh phải thực hiện tất cả các loại thoát của dấu phân tách trên các tham số chuỗi).
+0

Aaron, tôi chắc chắn Quotename sẽ làm việc 100% trừ khi có tên đối tượng với hơn 128 ký tự (Điều hiếm khi có). Tôi chỉ muốn chỉ ra điều này :) – Madhivanan

+3

@Madhivanan xin vui lòng cho tôi biết làm thế nào bạn có thể tạo một đối tượng với một tên> 128 ký tự (tôi nhận được một lỗi). 'QUOTENAME' được viết một cách rõ ràng để đối phó với các tên đối tượng và sự hiểu biết rằng một mã định danh không thể vượt quá 128 ký tự. –

+0

Bạn nói đúng. Tôi hiểu lầm điều đó. Tôi đã thấy mọi người sử dụng Quotename trong sql động hơn không chỉ trên tên đối tượng mà còn trên các giá trị quá để đặt dấu nháy đơn xung quanh nó. Giống như Quotename (@v, '' ''). Khi tôi đăng tôi lưu ý rằng trong tâm trí nhưng sai quy định tên đối tượng – Madhivanan

-3

Tại sao bạn chuyển tên đối tượng làm tham số?

Nếu bạn vượt qua chuỗi giá trị để @valuesname, mã của bạn nên được

create procedure queryfunctions 
(
@Tabname varchar(150),@colname varchar(150),@valuesname varchar(150) 
) 
as 
begin 
declare @sql varchar(4000) 
select @sql='select * from '[email protected]+' where '[email protected]+'='''[email protected]+'''' 
exec(@sql) 
end 

Không biết làm thế nào để sử dụng dấu nháy đơn trong sql động? Tham khảo này http://beyondrelational.com/modules/2/blogs/70/posts/10827/understanding-single-quotes.aspx

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