SQL Server에서 단일 세션 내에서 SQL 문을 동시에 실행할 수 있습니까?


16

임시 테이블을 사용하는 저장 프로 시저를 작성했습니다. SQL Server에서 임시 테이블은 세션 범위라는 것을 알고 있습니다. 그러나 세션의 기능에 대한 정확한 정보를 찾을 수 없었습니다. 특히,이 스토어드 프로 시저가 단일 세션에서 두 번 동시에 실행될 수있는 경우, 현재 임시 테이블을 공유하는 두 개의 실행으로 인해 해당 프로 시저 내의 트랜잭션에 대해 더 높은 분리 레벨이 필요합니다.

답변:


19

브렌트의 대답은 모든 실제적인 목적에 맞는지, 이것은 내가 대해 누군가 걱정을 본 적이 뭔가 아니지만, 이다 세션 범위의 #temp 테이블을 통해 서로 영향을 미치는 세션에서 저장 프로 시저의 여러 호출 가능한 .

좋은 뉴스는의이다 매우 야생 때문에 일어날 것 같지

1) # 저장 프로 시저 또는 중첩 배치 내에 선언 된 임시 테이블에는 실제로 세션 가시성 (또는 수명)이 없습니다. 그리고 이들은 지금까지 가장 일반적인 경우.

2) MultipleActiveResultsets 와 매우 이상한 비동기 클라이언트 프로그래밍 이 필요 하거나 저장 프로 시저가 중간에 결과 집합을 반환하고 클라이언트는 첫 번째 결과를 처리하는 동안 저장 프로 시저의 다른 인스턴스를 호출해야합니다.

다음은 좋은 예입니다.

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

어떤 출력

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

저장 프로 시저의 두 번째 호출이 행을 삽입 한 다음 첫 번째 호출이 클라이언트가 첫 번째 결과 집합에서 행을 페치하기를 기다리는 동안 #t에서 모든 행을 삭제했기 때문입니다. 첫 번째 결과 집합이 작 으면 행이 버퍼링되어 클라이언트에 아무것도 보내지 않고도 실행이 계속 될 수 있습니다.

당신이 이동하면

create table #t(id int)

저장 프로 시저에 출력합니다.

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

프로 시저 내에 임시 테이블이 선언 된 상태 에서 두 번째 쿼리를

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

다음과 같이 실패합니다.

'잘못된 개체 이름'#t '.'

저장 프로 시저 또는 중첩 배치 내에서 생성 된 #temp 테이블은 해당 저장 프로 시저 또는 배치와 호출 된 중첩 프로 시저 및 배치에서만 볼 수 있고 프로 시저 또는 배치가 종료되면 삭제됩니다.


12

동시에는 아닙니다. 다음과 같은 옵션이 있습니다.

  • 같은 세션에서 쿼리를 하나씩 실행
  • 임시 테이블에서 전역 임시 테이블로 전환하지만 (#TableName 대신 ## TableName 사용) 임시 테이블을 만든 세션이 닫히고 다른 활성 세션이 없으면 전역 임시 테이블이 자동으로 삭제됩니다. 그것에 대한 참조
  • TempDB에서 실제 사용자 테이블로 전환-거기에서 테이블을 만들 수는 있지만 서버를 다시 시작할 때 테이블이 사라진다는 점에 유의하십시오.
  • 사용자 데이터베이스에서 실제 사용자 테이블로 전환
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.