2011-02-14 5 views
2

저는 며칠 동안이 작업을 해왔고 적절한 해결책을 찾지 못했습니다. 누군가 도와 드릴 수 있기를 바랍니다.UNION 뷰를 동적 뷰로 다시 작성하십시오.

동일한 구조의 여러 데이터베이스 서버 (SQL Server)가 연결된 서버로 연결되어 있습니다.

  • 우리는 서버를 추가 할 때, 우리는 전망을 수정해야합니다 :

    CREATE VIEW Things_view AS 
        SELECT id, thing 
        FROM server1.database1.dbo.stuff 
        UNION ALL 
        SELECT id, thing 
        FROM server2.database2.dbo.stuff 
        UNION ALL 
        SELECT id, thing 
        FROM server3.database3.dbo.stuff 
    

    이 몇 가지 문제가 있습니다 : 우리는 모든 서버에서 노동 조합의 데이터가 있다는 견해 무리가있다.

  • 개발 환경에 개의 데이터베이스와 동일한 숫자의 데이터베이스가 필요하고 개의 가짜 서버가 있으므로 개의 뷰를 설치할 수 있습니다.
  • 일부 서버 에는 에 다른 서버의 데이터가 개 포함되어 있지 않습니다. 오늘날 우리는 이러한 서버에 대한 사용자 지정보기를 사용하여이 작업을 수행하지만 이는 배포상의 악몽입니다.

그래서 저는 이것을 동적으로 다시 쓰고 싶습니다. 목표는 다음과 같습니다.

  • 에 다른 수의 데이터베이스가 포함되도록 허용합니다. 그들은 에 단일 서버에 2 개 이상의 데이터베이스가있을 가능성이 있습니다.
  • 에 각 서버에 대해 에 포함될 다른 서버를 지정하는 방법을 결과에 포함하십시오.
  • 솔루션이 다소 유지 될 수 있도록 복잡성을 최소화하여 유지 관리 할 수있는 부분은 다소 입니다.
  • 소스가 제어되고 모든 서버에 사용할 수있는 솔루션 하나를 만듭니다.

그리고 가장 중요한 : 우리는 우리의 전체 응용 프로그램을 다시 작성하지 않아도

  • 이 같은 이름의보기로 노출.

물론 뷰나 함수에서 동적 SQL을 수행 할 수 없습니다. 저장 프로 시저로 다시 작성한 다음 OPENROWSET trick을 사용하여 저장된 proc을 뷰에서 쿼리했습니다. 데이터베이스 이름으로 proc를 완전히 한정해야하기 때문에 (데이터베이스 이름이 다르기 때문에)보다 동적 인 SQL이 필요했습니다. 그런 다음 마스터 데이터베이스에서 동의어를 속일 생각을했으나 유지 관리 및 소스 제어 목표를 위반했습니다.

필요하다면 서버 이름과 데이터베이스 이름 및 포함 플래그가있는 새 테이블을 만들면 문제가 없습니다. 실제로 이것은 각 환경에 대한 구성을 중앙 집중식으로 관리하기 때문에 이상적입니다.

저는 이것으로 완전히 당황했습니다. 이제 인터넷에 도움을 청합니다.당신이 최신 SQL 서버를

+0

보기를 사용해야합니까? 저장된 procs 가능합니까? – gbn

+0

저장된 proc은 궁극적으로 응용 프로그램에 동일한 이름의 뷰로 노출되는 한 괜찮습니다. – vincentj

+0

번호/서버 이름 변경 빈도는 얼마나됩니까? 데이터가 실시간이어야합니까? –

답변

0

보기를 조정하는 저장 프로 시저를 만드는 것입니다. 예를 들어 (테스트되지 않음) :

create procedure dbo.RecreateView 
as 
declare @sql varchar(max) 

select @sql = IsNull(@sql + 'union all ','') + 
       'select * from ' + name + '.dbo.YourView ' 
from sys.databases 
where name like 'DbNamePrefix%' 

set @sql = 'create view dbo.YourView as ' + @sql 
exec (@sql) 

데이터베이스를 추가하거나 예약 된 작업을 수행 한 후에도 저장 프로 시저를 호출 할 수 있습니다.

+0

우리는 2005 년과 2008 년 서버가 혼합되어 있습니다. OPENROWSET 트릭 작업을 만들기 위해 마스터 데이터베이스에서 뷰의 동의어를 만드는 방법에 대해 생각했지만 동의어를 수십 개 (각보기마다 하나씩) 유지해야하며 응용 프로그램 데이터베이스 외부에서 작업하는 것은 복잡합니다. 내가 소개하고 싶은지 모르겠다. – vincentj

2

한 가지 가능한 솔루션을 사용하는 경우 좋은 옵션이 될 것 동의어를 사용

+0

나는 이것을 고려했다. 그러나 우리의 소스 컨트롤을 망쳐 놓았다. 우리는 Redgate SQL Source Control을 사용하고 있습니다.보기가 재구성 될 때마다 소스 제어 시스템에 수정 된 것으로 표시되므로 무시할 수있는 방법이없는 것처럼 보입니다. 바람직하지 않게 수정 된보기를 실수로 배포하는 것은 너무 쉽습니다. – vincentj

0

서버 및 데이터베이스를 추적하는 테이블이있는 경우 해당 테이블의 트리거에서 동적으로 뷰를 작성할 수 있습니다.

이 질문에 대한 답변을보십시오. 동일한 것을 제안하고 트리거에서 뷰 정의를 변경하는 샘플 코드가 있습니다.

Dynamic table design (common lookup table), need a nice query to get the values

그것은 당신을 위해 일한다 수도 있습니다.

0

이것은 데이터웨어 하우스의 작업처럼 들립니다. http://en.wikipedia.org/wiki/Data_warehouse 데이터가 실시간이 아니도록 일정에 따라 실행해야합니다. 그것이 유일한 단점입니다.

server[n].database.tablename의 데이터를 아래 유사한 파일을 사용하여로드하십시오.

--Here is how you would administer the script. One single script that you would only need to modify when you added/removed servers. 
So you can easily add this to source control or whatever. You can also do all this, without linked servers, if you look at some ETL tools. like SSIS 

insert into dataserver1.datawarehouse.tablename select *,'svr1,'db','tablename' from svr1.db.tablename 
insert into dataserver1.datawarehouse.tablename select *,'svr2,'db','tablename' from svr1.db.tablename 
insert into dataserver1.datawarehouse.tablename select *,'svr3,'db','tablename' from svr1.db.tablename 
insert into dataserver1.datawarehouse.tablename select *,'svr4,'db','tablename' from svr1.db.tablename 
insert into dataserver1.datawarehouse.tablename select *,'svr5,'db','tablename' from svr1.db.tablename 
insert into dataserver1.datawarehouse.tablename select *,'svr6,'db','tablename' from svr1.db.tablename 
insert into dataserver1.datawarehouse.tablename select *,'svr7,'db','tablename' from svr1.db.tablename 
insert into dataserver1.datawarehouse.tablename select *,'svr8,'db','tablename' from svr1.db.tablename 

많은 삽입 문을 만들어야합니다. 가지고있는 각 서버/db/table 콤보 하나당 하나.

insert into dataserver1.datawarehouse.tablename select *,'svr1,'db','tablename' from svr1.db.tablename

그래서이 새 데이터베이스 테이블에 데이터를로드, 당신은 단순히 원본 서버 이름/databaseName을/TABLENAME이 SO .... 귀하의 데이터가이

col1 col2 col3 srvnam dbname tbl 
foo bar some MSSQL1 master mycooltable 
foo bar some MSSQL2 other mycooltable 
처럼 보이는 모든 행에 추가합니다

이제 테이블 하나에 대한 쿼리 만 수행하면됩니다. 정말 빠르고 깨끗합니다.

+0

뷰의 이름을 바꿀 수 없으므로 마침내 위의 스크립트 코드에서 *를 선택하여 기존보기를 만듭니다. –

0

다음은 내가 제안한 것입니다. 특정 서버의 각보기에 대한 구성을 저장할 테이블을 만듭니다. 그런 다음 동적 SQL을 작성하여 해당 구성을 기반으로보기 스크립트를 작성하십시오. 그런 다음 서버에서 뷰 스크립트를 실행하십시오. 새 서버를 추가하려면 변경중인보기에 대한 스크립트를 자동으로 다시 생성하기위한 트리거가있는 구성 테이블에 서버를 추가하십시오. 또는 테이블에서 스크립트를 다시 작성하여 실행하면 모든 배포의 표준 부분이됩니다.

관련 문제