SQL ifadelerinin SQL Server'da tek bir oturumda eşzamanlı olarak çalıştırılması mümkün müdür?


16

Geçici bir tablo kullanan saklı bir yordam yazdım. SQL Server'da geçici tabloların oturum kapsamlı olduğunu biliyorum. Ancak, bir oturumun tam olarak neler yapabileceğine dair kesin bilgi bulamadım. Özellikle, bu saklı yordamın tek bir oturumda eşzamanlı olarak iki kez yürütülmesi mümkünse, şimdi geçici bir tablo paylaşan iki yürütme nedeniyle bu yordamdaki bir işlem için önemli ölçüde daha yüksek bir yalıtım düzeyi gerekir.

Yanıtlar:


19

Brent'in cevabı tüm pratik amaçlar için doğru olsa da ve bu, birinin endişe duyduğunu gördüğüm bir şey olmasa da , bir oturumda saklanan bir yordamın birden çok çağrısının oturum kapsamındaki #temp tablosu aracılığıyla birbirini etkilemesi mümkündür. .

İyi haber şu ki, vahşi doğada olma ihtimali çok düşük çünkü

1) # Saklı yordamlar veya iç içe gruplar arasında bildirilen şablon tabloları aslında oturum görünürlüğüne (veya ömrüne) sahip değildir. Ve bunlar farkla en yaygın durumda.

2) ÇokluActiveResultsets ve çok garip bir zaman uyumsuz istemci programlama veya saklı yordamın bir sonuç kümesini ortaya döndürmesi ve istemcinin sonuçları ilk işlemden geçirirken saklı yordamın başka bir örneğini çağırması gerekir.

İşte örnek bir örnek:

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();
        }
    }
}

hangi çıktılar

Numer of rows in temp table 0
Hit any key to exit

çünkü saklı yordamın ikinci çağırma bir satır ekledi ve sonra ilk çağırma istemcinin satırları ilk sonuç kümesinden almasını beklerken #t içindeki tüm satırları sildi. İlk sonuç kümesi küçükse, satırların arabelleğe alınabileceğini ve yürütmenin istemciye hiçbir şey göndermeden devam edebileceğini unutmayın.

Eğer hareket ederseniz

create table #t(id int)

saklı yordam içine çıktı:

Numer of rows in temp table 1
Hit any key to exit

Ve yordam tablosunda yordamın içinde bildirilen ikinci sorguyu

cmd2.CommandText = "select * from #t";

Başarısız:

'Geçersiz nesne adı' #t '.'

Saklı yordam veya iç içe toplu iş içinde oluşturulan bir #temp tablosu yalnızca o saklı yordam veya toplu işte ve çağırdığı iç içe yordamlarda ve toplu işlerde görünür ve yordam veya toplu iş sona erdiğinde yok edilir.


12

Aynı anda değil. Seçenekleriniz şunları içerir:

  • Aynı oturumda sorguları birbiri ardına çalıştırın
  • Bir geçici tablodan genel geçici tabloya geçin (#TableName yerine ## TableName kullanın), ancak geçici tabloyu oluşturan oturum kapandığında genel geçici tablonun otomatik olarak bırakıldığını ve ona bir referans
  • TempDB'de gerçek bir kullanıcı tablosuna geçiş yapın - orada tablolar oluşturabilirsiniz, ancak sunucu yeniden başlatıldığında kaybolacaklarını unutmayın
  • Kullanıcı veritabanında gerçek bir kullanıcı tablosuna geçme
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.