Theo các bài kiểm tra trong bài đăng blog này, SQL Server sẽ thực hiện tham số hóa cho bạn, bằng cách gói câu lệnh của bạn trong sp_executesql, khi bạn sử dụng CommandType.Text
. Nhưng khi bạn sử dụng CommandType.StoredProcedure
bạn sẽ tham số hóa nó và do đó lưu cơ sở dữ liệu một số công việc. Phương pháp thứ hai nhanh hơn.
Chỉnh sửa:
Thiết lập
Tôi đã tự mình thực hiện một số bài kiểm tra và đây là kết quả.
Tạo thủ tục này:
create procedure dbo.Test
(
@Text1 varchar(10) = 'Default1'
,@Text2 varchar(10) = 'Default2'
)
as
begin
select @Text1 as Text1, @Text2 as Text2
end
Thêm dấu vết vào nó bằng cách sử dụng SQL Server Profiler.
Và sau đó gọi nó bằng mã sau:
using System;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
CallProcedure( CommandType.Text );
CallProcedure( CommandType.StoredProcedure );
}
private static void CallProcedure(CommandType commandType)
{
using ( SqlConnection connection = new SqlConnection("Data Source=localhost;Initial Catalog=Test;Integrated Security=SSPI;") )
{
connection.Open();
using ( SqlCommand textCommand = new SqlCommand("dbo.Test", connection) )
{
textCommand.CommandType = commandType;
textCommand.Parameters.AddWithValue("@Text1", "Text1");
textCommand.Parameters.AddWithValue("@Text2", "Text2");
using ( IDataReader reader = textCommand.ExecuteReader() )
{
while ( reader.Read() )
{
Console.WriteLine(reader["Text1"] + " " + reader["Text2"]);
}
}
}
}
}
}
}
Kết quả
Trong cả hai trường hợp, các cuộc gọi được thực hiện bằng RPC.
Đây là những gì dấu vết tiết lộ bằng cách sử dụng CommandType.Text
:
exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
Và đây là kết quả sử dụng CommandType.StoredProcedure
:
exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'
Như bạn có thể thấy, cuộc gọi văn bản được gói gọn trong một cuộc gọi tới sp_executesql
để nó được tham số hóa đúng. Điều này tất nhiên sẽ tạo ra một chi phí nhỏ và do đó, tuyên bố trước đây của tôi rằng sử dụng CommandType.StoredProcedure
nhanh hơn vẫn còn.
Một điều đáng chú ý khác, và cũng là một loại lỗi giao dịch ở đây, là khi tôi tạo thủ tục mà không có giá trị mặc định, tôi đã gặp lỗi sau:
Msg 201, Mức 16, Trạng thái 4, Kiểm tra quy trình, Dòng 0 Quy trình hoặc chức năng 'Kiểm tra' mong đợi tham số '@ Text1', thông số này không được cung cấp.
Lý do cho điều này là cách gọi đến sp_executesql
được tạo, như bạn có thể thấy các tham số được khai báo và khởi tạo, nhưng chúng không được sử dụng . Để cuộc gọi hoạt động, nó phải trông như thế này:
exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
Có nghĩa là, khi bạn đang sử dụng CommandType.Text
bạn phải thêm các tham số vào CommandText
trừ khi bạn luôn muốn các giá trị mặc định được sử dụng.
Vì vậy, để trả lời câu hỏi của bạn
- Sử dụng
CommandType.StoredProcedure
nhanh hơn. - Nếu bạn đang sử dụng
CommandType.Text
, sau đó bạn sẽ phải thêm tên tham số vào lệnh gọi thủ tục trừ khi bạn muốn sử dụng các giá trị mặc định.