2009-07-14 4 views
4

2 가지 절차가 있습니다. 임시 테이블과 첫 번째 proc에서 생성 된 임시 테이블을 사용하는 다른 테이블 (또는 여러 테이블)을 만드는 방법. 이것은 나쁜 형태로 간주됩니까? 나는 여기에있는 기존의 코드베이스에 들어가고 있으며,이 패턴을 많이 사용한다. 그것은 확실히 나를 귀찮게하지만 그것이 명백하게 나쁜 생각이라고 말할 수는 없습니다. 나는 그저 짜증나는 패턴이라고 생각합니다. 썩은 냄새가 나지만 무엇을 말할 수는 없습니다. 나는 테이블을 로컬로 빌드 한 다음 exec로 채우기를 원합니다. 그러나 그것은 기존의 코드베이스에서는 특이한 하나의 테이블 만 반환하는 procs를 필요로합니다.은 나쁜 형식으로 간주되는 절차에서 임시 테이블을 공유합니까?

이런 임시 테이블 공유에서 SQL 전문가를 멀리합니까? 그렇다면 왜? 나는 이것에 대해 고려 된 의견을 형성하려고 노력 중이며 약간의 의견을 원합니다.

보기가 가능한 대안이 될 수 있습니까?

실적은 어떻습니까? @table을 로컬로 빌드하거나 "채우기"proc에서 #table을 빌드하는 것이 더 낫지 않습니까?

여기에 모든 방법의 좋은 토론있다 :이 똑같은 문제가 발생했습니다 http://www.sommarskog.se/share_data.html

답변

3

프로 시저 시그니처에서 명시 적으로 호출되지 않은 대역 외 매개 변수 ('컨텍스트 매개 변수')를 전달하기 때문에 프로그래밍 패러다임으로 추악합니다. 이렇게하면 숨겨진 종속성이 생겨 스파게티 효과가 발생합니다.

그러나 SQL의 특정 컨텍스트에서는 대체 없음 만 있습니다. SQL은 데이터 세트와 작동하며이 데이터 세트를 프로 시저 매개 변수로 앞뒤로 전달할 수 없습니다. 대안이 거의 없습니다.

  • 클라이언트를 통해 전달하십시오. 너무 분명해서 진짜 옵션이 아닙니다.
  • 구분 기호가있는 XML 또는 문자열로 결과를 나타냅니다. 어떤 스트레칭으로도 진지한 선택이 아니라, 좋은 '프로그래밍'의미 (예 : Demeter Law 적합성)를 줄 수도 있지만, 성능이 향상되면 정말 빨기도합니다.
  • Raj와 같은 공유 테이블 (tempdb 또는 appdb에 있음). #temp 자동 유지 보수 (참조 횟수에 대한 정리가 0이 됨)가 느슨해 지므로 작성 경쟁 조건에 대비해야합니다. 또한 그들은 아무 이유없이 커질 수 있습니다. (더 이상 #temp 테이블과 같은 별도의 행 집합으로 세션별로 분할되지 않습니다.)
  • @ 테이블. 그것들은 선언 문맥 (즉, 프로 시저)에 적용되며 프로 시저간에 앞뒤로 전달할 수 없습니다. 나는 또한 some nasty problems under memory pressure을 발견했다.
0

가. 개인적인 경험으로 말할 수있는 것 :

여러 절차에서 #temp 테이블을 사용하지 않으려면 사용할 수있는 방법이 있습니다. #temp 테이블은 잃어 버리기 쉽고 조심하지 않으면 tempdb를 쉽게 늘릴 수 있습니다.

경우에 따라이 방법을 피할 수 없습니다 (예 : 보고서 구성에 따라 데이터를 다르게 만드는 특정보고 기능). 신중하게 관리한다면, 나는 이러한 상황에서 받아 들일 수 있다고 믿습니다.

0

임시 테이블을 공유하는 것은 좋지 않습니다. 그러나 우리는 테이블 레벨 데이터가 동시에 두 개의 procs에 의해 조작되어서는 안되며, 더티 읽기/쓰기 시나리오를 이끌어 낼 필요가 있습니다. 이것은 또한 하나의 테이블 [중앙화 된]과 그것에 작동하는 procs를 가지고 동기화 - 업 데이터를 갖는 것을 도울 것입니다. 성능과 관련하여 동일한 임시 데이터를 공유하는 여러 개의 procs를 사용하면 성능이 저하됩니다. 그러나 동시에 개별 테이블을 사용하면 메모리 사용량이 증가합니다.

0

나는이 접근 방식을 약간의 경우에 사용했습니다. 하지만 항상 #tablename을 사용하는 것이 아니라 임시 테이블을 완전한 테이블로 선언합니다.

CREATE TABLE [tempdb].[dbo].[tablename] 

이러한 접근 방식을 사용하면 임시 테이블을 쉽게 추적 할 수 있습니다.

주권

+1

그 테이블은 "읽기"proc 파일에 대한 여러 번의 후속 호출에서 공유되지 않습니까?당신이 간헐적으로 실패를 디버그하는 것을 볼 수있는 지점처럼 보입니다. – jcollum

+0

이것은 전역 임시 테이블 (## temp)과 어떻게 다른가요? –

+0

## temp를 생성 한 연결이 닫히면 temp가 삭제됩니다. – JeffO

1

공유 임시 테이블의 가장 큰 문제는 언뜻보기에 나타나지 않을 수있는 방법으로 외부 종속성을 도입한다는 것이다. 프로 시저 p2를 호출하는 프로 시저 p1이 있고 두 프로 시저간에 정보를 전달하는 데 temp 테이블 # t1이 사용된다고 가정 해보십시오. p2를 독립적으로 실행하여 그 기능을 확인하려면 실행하기 전에 # t1을 정의하는 "하네스"를 만들어야합니다. T-SQL에서 임시 테이블을 사용하는 것은 다른 언어로 전역 변수를 사용하는 것과 같습니다. 권장하지는 않지만 때로는 피할 수없는 경우도 있습니다.

이제 SQL Server 2008에는 테이블 반환 매개 변수가 있지만 Microsoft는이 릴리스에서 읽기 전용으로 설정했습니다. 여전히, 이전 시나리오에서 임시 테이블을 사용할 필요가 없다는 것을 의미합니다.

필자의 조언은 사용하는 것이지만 사용법을 철저히 문서화하는 것입니다.실행할 임시 테이블에 의존하는 proc를 가지고 있다면 주석에서 이것을 호출하십시오.

0

임시 테이블을 사용하지 않도록하는 또 다른 기술은 소위 "SPID 키"테이블입니다. 대신 임시 테이블, 당신은 다음과 같은 특성을 가진 일반 테이블을 정의

SELECT @var = some_value 
FROM spid_table 
WHERE -- some condition 
AND spid = @@SPID; 

및 처리의 말 :

당신의 절차에

CREATE TABLE spid_table 
(
    id INT IDENTITY(1, 1) NOT NULL, 
    -- Your columns here 
    spid INT NOT NULL DEFAULT @@SPID, 
    PRIMARY KEY (id) 
); 

, 당신은 다음과 같은 코드가있을 것입니다

DELETE FROM spid_table 
WHERE spid = @@SPID; 

이 단점은 테이블이 나머지 데이터베이스와 동일한 복구 모델을 사용하므로 이러한 모든 일시적인 삽입, 업데이트 및 삭제가 기록된다는 것입니다. 유일한 장점은 임시 테이블을 사용하는 것보다 종속성이 더 분명하다는 것입니다.

0

2 번째 proc이 임시 테이블 &의 존재를 확인하는 경우 앞으로 이동하는지 확인하는 것이 좋습니다. 또한 임시 테이블이 없으면 사용자에게 proc1을 먼저 실행하도록 요청하는 오류를 발생시킬 수 있습니다.

왜 작업을 2 개의 저장된 procs로 나누었습니까? 1 proc에서 일을 처리 할 수 ​​없습니까?

+0

좋은 질문이지만 대답 할 수있는 사람은 아닙니다. 누군가 어딘가에 좋은 생각, 유일한 해결책 또는 수용 가능한 결정했습니다. 그런 다음에 붙어있었습니다. – jcollum

+0

프로 시저에 결합 할 수 없습니까? – shahkalpesh

1

때로는 이것이 유일한 방법입니다. 이렇게해야 할 경우 DOCUMENT, DOCUMENT, DOCUMENT 사실을 확인해야합니다. 여기에 분명히, 매개 변수 섹션에서 주석으로 테이블 정의를 넣어 만드는 하나의 방법 ...

CREATE PROCEDURE xyz 
(
    @param1 int   --REQUIRED, what it does 
    ,@param2 char(1)  --OPTIONAL, what it does 
    ,@param3 varchar(25) --OPTIONAL, what it does 
    --this temp table is required and must be created in the calling procedure 
    --#TempXyz (RowID  int   not null primary key 
    --   ,DataValue varchar(10) not null 
    --   ,DateValue datetime  null 
    --  ) 
) 

또한 임시 테이블이 만들어 호출 프로 시저의 문서는 ....입니다

--** THIS TEMP TABLE IS PASSED BETWEEN STORED PROCEDURES ** 
--** ALL CHANGES MUST TAKE THIS INTO CONSIDERATION!!! ** 
CREATE TABLE #TempXyz 
(RowID  int   not null primary key 
,DataValue varchar(10) not null 
,DateValue datetime  null 
) 
관련 문제