2014-05-22 2 views
-5

필자는 정확한 목표를 달성하는 다음 코드를 작성했지만 비효율적이라고 확신합니다. 누군가 그것을 할 수있는 더 좋은 방법을 제공 할 수 있습니까? 감사.내 코드를 개선 할 수 있습니까?

CREATE TABLE #dbnames (name nvarchar(50)) 

DECLARE @startdate datetime 
DECLARE @enddate datetime 
DECLARE @dbname nvarchar (50) 

SET @startdate = '2014-01-01' 
SET @enddate = '2014-02-01' 

WHILE @startdate < @enddate + 1 

BEGIN 

-- Add database names to table 
SET @dbname = CONVERT(VARCHAR(6), @startdate, 12) 

INSERT #dbnames 
SELECT DISTINCT d.dbname 
FROM Databases d 
WHERE d.dbName = @dbname 

SET @startdate = DATEADD(DAY,1,@startdate) 

END 

SELECT * FROM #dbnames 

DROP TABLE #dbnames 
+3

왜 당신은 그 비효율적이라고 생각합니까? – Dynelight

+2

''비효율적이라고 확신한다 ''- 이것을 확인하기 위해 어떤 측정을 했습니까? – David

+0

저는 SQL 프로그래밍에 새로운 것이 있습니다. 그래서 저는 그렇게 생각합니다. – user3607525

답변

0

글쎄, 당신은 while 루프를 사용하고 있습니다. 이것은 집합 기반 언어로 절차 적 프로그래밍을하고 있다는 표시입니다. 큰 코드 냄새가납니다.

create table #dbnames 
(
    name nvarchar(50) not null primary key clustered , 
) 

declare @dtFrom date = '2014-01-01' 
declare @dtThru date = '2014-12-31' 

;with calendar as 
(select today = @dtFrom 
    union all 
    select tomorrow = dateadd(day,1,today) 
    from calendar 
    where dateadd(day,1,today) <= @dtThru 
) 
insert #dbNames 
select d.dbName 
from dbo.Databases d 
join calendar  c on convert(varchar(6),c.today,12) = d.dbname 
option(maxrecursion 0) 

을하지만 값의 아주 작은 영역에서 찾고 있기 때문에, 당신은 쉽게

insert #dbnames 
select distinct d.dbname 
from Databases d 
where d.dbName in ('140101' , '140102' , ... , '140131 , '140201') 

select distinct은 말할 수 :

이러한 라인을 따라 CTE를 시도 할 수 있습니다 코드 냄새도 있습니다 : Databases 테이블에 실제로 같은 이름의 데이터베이스가 두 개 이상 있습니까?

+0

실제로. 절차 적 프로그래밍은 제가 항상 그렇게 해왔 던 것입니다. 불행하게도 그것은 제가 더 효율적인 방법이 있다고 의심했던 또 다른 이유라고 생각하는 것입니다. 몇 달 분량의 데이터베이스가 있으므로 값의 도메인이 예제보다 크고 DISTINCT가 필요 없다는 것이 옳습니다. – user3607525

0

당신 수 : 임시 테이블에

  • 삽입 모든 날짜 및 테이블 "데이터베이스"(그래서 기본적으로 먼저 모든 데이터베이스 이름의 임시 테이블을 만들에 모든 것을 한 번에 가입 너는에 관심이있다).

  • 2014 년 2 월에 "2014-02"로 시작하는 데이터베이스 이름을 찾으려면 바로 가기를 사용하십시오.

하지만 더 중요한 사항 : 특정 문제를 해결하려고합니까? 솔루션에 만족하지 않으십니까? 아니면 다른 접근법을 배우고 싶습니까?

제안 사항은 가독성이나 성능을 크게 향상시키지 않으므로 목표를 설정하는 것이 중요합니다.

데이터베이스가 효율적인 쿼리를 사용하여 데이터를 수집하는 데 유익하다는 것을 기억하십시오. 스토어드 프로 시저에서 루프 및 커서와 같은 것들로부터 가능한 한 멀리 떨어져 있습니다.

+0

위의 몇 가지 생각합니다. 이 코드는 특정 데이터베이스에서 추출 할 항목 목록을 포함하는 각 데이터베이스에서 테이블을 읽는 '내부'루프 (CURSOR FOR)를 추가하는 위치에 설치됩니다. 몇 개월 간의 데이터베이스에서 합쳐진 값의 테이블을 만드는 것이고 나는 전체 스토어드 프로 시저가 다소 프로세스 집약적 일 것이라고 기대한다. – user3607525

관련 문제