SQL động - EXEC (@SQL) so với EXEC SP_EXECUTESQL (@SQL)


95

Ưu và nhược điểm trong thế giới thực của việc thực thi một lệnh SQL động trong một thủ tục được lưu trữ trong SQL Server bằng cách sử dụng

EXEC (@SQL)

đấu với

EXEC SP_EXECUTESQL @SQL

?

Câu trả lời:


96

sp_executesqlcó nhiều khả năng thúc đẩy việc tái sử dụng kế hoạch truy vấn. Khi sử dụng sp_executesql, các tham số được xác định rõ ràng trong chữ ký gọi. Bài báo xuất sắc này mô tả quá trình này .

Tài liệu tham khảo được trích dẫn cho nhiều khía cạnh của sql động là Erland Sommarskog's phải đọc: " Lời nguyền và phước lành của SQL động ".


21

Điều quan trọng về SP_EXECUTESQL là nó cho phép bạn tạo các truy vấn được tham số hóa, điều này rất tốt nếu bạn quan tâm đến SQL injection.


1
Tôi không nghĩ rằng bạn có thể tham số hóa một sql động mà không có nó ??
DJ.

EXEC ('SELECT * FROM FOO WHERE ID =?', 123) sẽ thay thế trình giữ chỗ tham số "?" với giá trị 123 và sau đó thực hiện truy vấn, trả lại kết quả cho SELECT * FROM FOO WHERE ID = 123
Peter Wone

1
Rất tiếc, cú pháp đó chỉ có sẵn cho các máy chủ được liên kết.
Peter Wone

1
Hoàn toàn là một trong những lý do lớn nhất để sử dụng sp_executesql nếu xây dựng truy vấn động để ngăn chặn việc tiêm sql.
Steven Rogers

5

Bài viết Sử dụng sp_executesql của Microsoft khuyến nghị sử dụng sp_executesqlthay vì executecâu lệnh.

Bởi vì thủ tục được lưu trữ này hỗ trợ thay thế tham số , sp_executesql linh hoạt hơn EXECUTE; và vì sp_executesql tạo các kế hoạch thực thi có nhiều khả năng được sử dụng lại bởi SQL Server, sp_executesql hiệu quả hơn EXECUTE.

Vì vậy, lấy đi: Đỗ không sử dụng executetuyên bố . Sử dụng sp_executesql.


7
Hành trang của bạn không phải lúc nào cũng có. Đôi khi không có phần thưởng hiệu quả bằng cách sử dụng sp_executesql, nhưng bạn có thể bảo vệ mã của mình khỏi cuộc tấn công tiêm sql. Đôi khi bạn không thể sử dụng sp_executesql theo cách mà bạn có thể sử dụng execute, vì vậy ... ai đó đã nói - không có viên đạn bạc. Tôi đồng ý.
OzrenTkalcecKrznaric

Đúng, Microsoft nên đặt nó là "có nhiều khả năng hiệu quả hơn". Và làm trong nghề mấy năm, tôi thấy có những trường hợp sp_executesqlkhông dùng được để thay thế execute. Có lẽ tôi nên đặt vấn đề mà tôi đang cố gắng nhấn mạnh là: Sử dụng sp_executesqlthay vì execute bất cứ khi nào có thể .
Gan

2

Tôi luôn sử dụng sp_executesql những ngày này, tất cả những gì nó thực sự là một trình bao bọc cho EXEC xử lý các tham số & biến.

Tuy nhiên, đừng quên OPTION RECOMPILE khi điều chỉnh các truy vấn trên cơ sở dữ liệu rất lớn, đặc biệt khi bạn có dữ liệu trải dài trên nhiều cơ sở dữ liệu và đang sử dụng CONSTRAINT để hạn chế việc quét chỉ mục.

Trừ khi bạn sử dụng OPTION RECOMPILE, máy chủ SQL sẽ cố gắng tạo kế hoạch thực thi "một kích thước phù hợp với tất cả" cho truy vấn của bạn và sẽ chạy quét chỉ mục đầy đủ mỗi khi nó được chạy.

Điều này kém hiệu quả hơn nhiều so với tìm kiếm và có nghĩa là nó có khả năng quét toàn bộ các chỉ mục bị giới hạn trong phạm vi mà bạn thậm chí không truy vấn: @


-2
  1. Khai báo biến
  2. Đặt nó bằng lệnh của bạn và thêm các phần động như sử dụng giá trị tham số của sp (ở đây @IsMonday và @IsTuesday là tham số sp)
  3. thực hiện lệnh

    declare  @sql varchar (100)
    set @sql ='select * from #td1'
    
    if (@IsMonday+@IsTuesday !='')
    begin
    set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
    end
    exec( @sql)

15
Điều này mở cho SQL injection, nếu bạn đặt ví dụ: "a '; DROP DATABASE DATABASE_NAME; GO;';" trong biến @IsMonday
Erik A. Brandstadmoen

nó có dễ bị lệnh sql không nếu @IsMonday là int?
Vikas Rana

@VikasRana @IsMonday không được intở trong SQL động. Lưu ý rằng @sql được khai báo là varcharhoặcnvarchar
Weihui Guo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.