Trong khi câu trả lời của dầu Brent là đúng cho cho tất cả các mục đích thực tế, và đây không phải là một cái gì đó mà tôi từng thấy một người nào đó lo lắng về, nó là có thể cho nhiều lời gọi của một thủ tục lưu trữ trong một phiên để ảnh hưởng lẫn nhau thông qua một bảng #temp phiên scoped .
Tin tốt là nó cực kỳ khó xảy ra trong tự nhiên bởi vì
1) #Temp bảng được khai báo bên trong một thủ tục được lưu trữ hoặc các lô được lồng không thực sự có khả năng hiển thị phiên (hoặc trọn đời). Và đây là bởi đến nay các trường hợp phổ biến nhất.
2) Nó yêu cầu MultipActiveResultsets và một số chương trình máy khách không đồng bộ rất lạ hoặc để thủ tục được lưu trữ trả về một tập kết quả ở giữa và máy khách gọi một phiên bản khác của thủ tục được lưu trữ trong khi xử lý kết quả từ lần đầu tiên.
Đây là một ví dụ giả định:
using System;
using System.Data.SqlClient;
namespace ado.nettest
{
class Program
{
static void Main(string[] args)
{
using (var con = new SqlConnection("Server=localhost;database=tempdb;integrated security=true;MultipleActiveResultSets = True"))
{
con.Open();
var procDdl = @"
create table #t(id int)
exec ('
create procedure #foo
as
begin
insert into #t(id) values (1);
select top 10000 * from sys.messages m, sys.messages m2;
select count(*) rc from #t;
delete from #t;
end
');
";
var cmdDDL = con.CreateCommand();
cmdDDL.CommandText = procDdl;
cmdDDL.ExecuteNonQuery();
var cmd = con.CreateCommand();
cmd.CommandText = "exec #foo";
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
var cmd2 = con.CreateCommand();
cmd2.CommandText = "exec #foo";
using (var rdr2 = cmd2.ExecuteReader())
{
}
while (rdr.Read())
{
}
rdr.NextResult();
rdr.Read();
var rc = rdr.GetInt32(0);
Console.WriteLine($"Numer of rows in temp table {rc}");
}
}
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}
đầu ra nào
Numer of rows in temp table 0
Hit any key to exit
bởi vì lệnh gọi thứ hai của thủ tục được lưu trữ đã chèn một hàng và sau đó xóa tất cả các hàng khỏi #t trong khi lệnh gọi đầu tiên đang chờ máy khách tìm nạp các hàng từ tập kết quả đầu tiên. Lưu ý rằng nếu tập kết quả đầu tiên nhỏ, các hàng có thể được đệm và thực thi có thể tiếp tục mà không gửi bất cứ thứ gì cho máy khách.
Nếu bạn di chuyển
create table #t(id int)
vào thủ tục lưu trữ, nó xuất ra:
Numer of rows in temp table 1
Hit any key to exit
Và với bảng tạm thời được khai báo bên trong thủ tục, nếu bạn thay đổi truy vấn thứ hai thành
cmd2.CommandText = "select * from #t";
Nó thất bại với:
'Tên đối tượng không hợp lệ' #t '.'
Bởi vì bảng #temp được tạo bên trong một thủ tục được lưu trữ hoặc lô được lồng chỉ có thể nhìn thấy trong quy trình hoặc lô được lưu trữ đó và trong các quy trình và lô được lồng mà nó gọi và bị hủy khi thủ tục hoặc lô kết thúc.