Sp_executesql có thể được cấu hình / sử dụng theo mặc định không?


10

Tôi đang xem xét một ứng dụng sử dụng các truy vấn sql rất năng động đối với SQL Server. Nhìn vào các truy vấn được xây dựng theo những cách rất kỳ lạ và phức tạp, nhưng đó là một câu chuyện khác, tôi nói với nó để đưa ra một lý do chính đáng để tôi không thể (quá ngu ngốc) tự tìm ra mọi thứ ... Tôi không thể thấy bất kỳ mã nào mà các truy vấn được gói bằng sp_executesql.

Nhưng khi tôi theo dõi, tôi có thể thấy rất nhiều truy vấn được gói lại sp_executesql. Toàn bộ giải pháp ứng dụng thậm chí không chứa lệnh nào sp_executesqlcả.

Vì vậy, tôi tự hỏi nếu có một loại cấu hình mà tôi chưa biết có buộc phần mềm phải bọc các truy vấn với sp_executesql theo mặc định không?

Điều gì có thể gây ra hành vi này?

Câu trả lời:


11

Lý do các câu lệnh SQL được gói gọn sp_executesqllà cài đặt thuộc SqlCommand.Commandtypetính và chuyển bất kỳ Tham số nào cho lệnh.

SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.StoredProcedure;                
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();

Đoạn mã trên kết thúc bằng T-SQL này:

exec proc1 @param1=1
SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.Text;                
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();

Mã này kết thúc bằng việc thực thi T-SQL sau:

exec sp_executesql N'proc1',N'@param1 int',@param1=1

Bổ sung 23.12.15: Sử dụng một CommandType.Textlệnh, kết quả tương tự nhau: Ngay sau khi một tham số được thêm vào đối tượng lệnh, .NET sẽ bọc toàn bộ truy vấn vào sp_executesqlvà chuyển các tham số cho nó.

Bổ sung: Sau khi đi sâu vào sp_executesql, tham số đánh hơi và lên kế hoạch lưu trữ hành vi này của các lớp .NET hoàn toàn có ý nghĩa để tránh biên dịch truy vấn thường xuyên và số lượng kế hoạch. Vì vậy, về cơ bản, nó được thiết kế để đảm bảo hiệu năng SQL Server tốt hơn nói chung đồng thời có thể dẫn đến hiệu suất kém của một số truy vấn (vấn đề đánh hơi tham số) được sử dụng với các giá trị tham số khác với kế hoạch truy vấn được tạo ban đầu.

Xem:

Mẫu trên được tạo bằng .NET Framework 4.5 và SQL Server 2008 Developer Edition.


5

Nếu đây là một ứng dụng .NET, thì rất có thể đó là kết quả của SqlCommand.ExecuteReader () được gọi. Theo trang lớp SqlCommand chính , trong lưới các mô tả phương thức trong phần "Ghi chú", bên dưới ExecuteReader, nó nói:

Thực hiện các lệnh trả về hàng. Để tăng hiệu suất, ExecuteReader gọi các lệnh bằng cách sử dụng thủ tục lưu trữ hệ thống sp_executesql của Transact-SQL . Do đó, ExecuteReader có thể không có hiệu ứng mà bạn muốn nếu được sử dụng để thực thi các lệnh như câu lệnh SET Transact-SQL.

Bây giờ tôi không có thời gian để kiểm tra điều này để xác nhận mô tả của họ, nhưng nó đủ dễ để tạo một ứng dụng bảng điều khiển đơn giản thực hiện cuộc gọi rất đơn giản, chuyển qua một số văn bản truy vấn và bao gồm một tham số được cung cấp kèm theo SqlParameter. Tôi đoán là như vậy ExecuteNonQueryExecuteScalarcũng sử dụng sp_executesqlvì chúng cũng cho phép truyền tham số, vậy tại sao lại có một đường dẫn khác cho cách chúng được thực thi?

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.