Podczas gdy odpowiedź Brenta jest poprawna dla wszystkich praktycznych celów i nie jest to coś, o czym ktoś jeszcze się martwi, możliwe jest , że wielokrotne wywołanie procedury przechowywanej w sesji wpływa na siebie nawzajem poprzez tabelę #temp o zasięgu sesji .
Dobra wiadomość jest taka, że jest bardzo mało prawdopodobne, aby zdarzyło się to na wolności, ponieważ
1) Tabele #Temp zadeklarowane w procedurach przechowywanych lub zagnieżdżonych partiach w rzeczywistości nie mają widoczności sesji (ani czasu życia). I są to zdecydowanie najczęstsze przypadki.
2) Wymaga MultipleActiveResultset i albo jakiegoś bardzo dziwnego programowania klienta asynchronicznego, albo procedury składowanej, aby zwrócić zestaw wyników w środku, a klient wywołuje inną instancję procedury składowanej podczas przetwarzania wyników od pierwszego.
Oto wymyślony przykład:
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();
}
}
}
które wyjścia
Numer of rows in temp table 0
Hit any key to exit
ponieważ drugie wywołanie procedury składowanej wstawiło wiersz, a następnie usunęło wszystkie wiersze z #t, podczas gdy pierwsze wywołanie czekało na pobranie przez klienta wierszy z pierwszego zestawu wyników. Zauważ, że jeśli pierwszy zestaw wyników był mały, wiersze mogą zostać buforowane, a wykonywanie może być kontynuowane bez wysyłania czegokolwiek do klienta.
Jeśli przeniesiesz
create table #t(id int)
do procedury przechowywanej wyprowadza:
Numer of rows in temp table 1
Hit any key to exit
A z tabelą temp zadeklarowaną w ramach procedury, jeśli zmienisz drugie zapytanie na
cmd2.CommandText = "select * from #t";
Nie działa z:
„Niepoprawna nazwa obiektu„ #t ”.”
Ponieważ tabela #temp utworzona w ramach procedury składowanej lub partii zagnieżdżonej jest widoczna tylko w tej procedurze składowanej lub partii oraz w procedurach zagnieżdżonych i partiach, które wywołuje, i jest niszczona po zakończeniu procedury lub partii.