2012-12-07 4 views
8

SQL Server 버전 - 2008 R2받기 SQL 서버 데이터베이스 간 종속성

나는 유지 보수 인수의 목적으로하는 DMS 솔루션을 평가하는 작업입니다. 원래의 솔루션에는 제조업체 관련 데이터가있는 하나의 중앙 데이터베이스가 있습니다. 또한 각 딜러마다 하나의 데이터베이스가 있으므로 많은 데이터베이스 종속성이 있습니다.

문제점 :

  • 없음 DB 문서
  • 없음 코드는 힙의
  • 많은
  • 표준 객체의 명명 규칙
  • 중앙 DB는 460+ 테이블과 900+ sprocs가있다을 댓글 없음 , 기타 개체
  • 각 딜러 DB는 370+ 테이블과 2350+ SProcs를 추가로 포함합니다 다른 객체 첫 번째 단계로

에 n은 나는 크로스 데이터베이스 종속성을 포함한 객체 종속성을 이해하는 것이 중요하다위한 DB의 전체 청소를 추천하고있다. 레드 게이트 솔루션을 사용해 보았지만 출력량이 너무 많습니다. 필자가 원하는 것은 종속성이없는 데이터베이스의 개체 목록입니다. 다른 개체에 의존하지도 않고 종속 된 개체도 없습니다. - 종속성 -되는 I는 각 DB에서 설정이 결과를 삽입합니다 나는 테이블을 생성한다

SELECT 
DB_NAME() referencing_database_name, 
OBJECT_NAME (referencing_id) referencing_entity_name, 
ISNULL(referenced_schema_name,'dbo') referenced_schema_name, 
referenced_entity_name, 
ao.type_desc referenced_entity_type, 
ISNULL(referenced_database_name,DB_NAME()) referenced_database_name 
FROM sys.sql_expression_dependencies sed 
JOIN sys.all_objects ao 
ON sed.referenced_entity_name = ao.name 

: 여기

내가 종속성 목록을 가져 오는 데 사용했던 스크립트입니다. 다음 단계로 데이터베이스의 모든 개체 목록을 포함하는 AllObjects라는 또 다른 테이블을 만들 것입니다. 다음은이 작업을 수행 할 수있는 스크립트입니다 : 이제

SELECT 
DB_NAME() DBName, 
name, 
type_desc 
FROM sys.all_objects 
WHERE type_desc IN 
(
'VIEW', 
'SQL_TABLE_VALUED_FUNCTION', 
'SQL_STORED_PROCEDURE', 
'SQL_INLINE_TABLE_VALUED_FUNCTION', 
'USER_TABLE', 
'SQL_SCALAR_FUNCTION' 
) 

, 내가 찾고 있어요 개체의 목록을 제공해야하는 종속 테이블의 referenced_entity_name 컬럼에 표시되지 않습니다이 테이블에서 이름의 목록입니다.

이제
SELECT 
AO.DBName, 
AO.name, 
AO.type_desc 
FROM AllObjects AO 
LEFT OUTER JOIN Dependencies D ON 
D.referenced_database_name = AO.DBName AND 
D.referenced_entity_name = AO.name AND 
D.referenced_entity_type = AO.type_desc 
WHERE 
D.referenced_database_name IS NULL AND 
D.referenced_entity_name IS NULL AND 
D.referenced_entity_type IS NULL 

질문은 :

  1. 일부 개체 종속성은 출력에서 ​​누락 된 것으로 보인다. 나는 가 무엇입니까?
  2. 내 결과가 정확한지 어떻게 확인합니까?
  3. 다른 방법이 있나요? 결과와 다시 비교할 수 있습니까? 사전에

감사합니다,

주권

+0

입니까? –

+0

하지만 type = 'U'는 사용자 테이블 만 제공합니다. 맞습니까? 또한 다른 사용자가 만든 개체를 고려해야합니다. – Raj

+0

죄송합니다. "and is_ms_shipped = 0"이 (가) 두 번째 쿼리에 더 적합 할 수 있습니다. 이것은 시스템 특정 객체를 제외해야합니다. –

답변

3

오, MS는 sys.sql_expression_dependencies와 데이터베이스 간 종속성을 검출하기에 좋은 노력을했다,하지만 난 그것을 전에 일을 그리워 보았다. 귀하의 경우에는 필자가 종속성이 누락 된 사례를 발견하고 백 트랙킹을 시작합니다. 쿼리에서 삭제 한 적이 있습니까? 그렇다면 쿼리를 수정하십시오. sys.sql_expression_dependencies는 특정 클래스의 종속성을 생략합니까? 어떤 조건에서? 동적 SQL이 비난합니까? 기타

또한 sys.sql_modules의 각 개체에 대해 sp_refreshsqlmodule을 실행 한 다음 코드를 다시 실행해야합니다. SQL Server가 종속성 정보를 새로 고칠 수 있도록합니다 (능력을 최대한 활용하여).

이제 유효성 검사를 위해 추적을 설정하고 이벤트 114, "스키마 개체 액세스 이벤트 감사"및 저장 프로 시저 및/또는 RPC 호출의 시작 및 완료 이벤트를 수신하십시오. 열 DatabaseName, ParentName, ObjectName, ServerName, SPIDRequestID (MARS 사용 연결의 경우)을 포함합니다. 어쩌면 다른 사람들도있을 것입니다. "감사 스키마 개체 액세스 이벤트"는 개체에 액세스 할 때마다 발생하므로이 추적이 실행되는 동안 응용 프로그램을 실행 한 다음 SPID + RequestId를 사용하여 데이터를 대조하고 sys.sql_expression_dependencies를 사용하여 결과와 비교합니다. 의존성 데이터에 나타나지 않는 추적 데이터에 아무 것도 없으면 뭔가를 놓친 것입니다.

7

결과를 다음 스크립트에서 찾은 결과와 비교할 수 있습니다. 여기 당신은 또한 시스템 개체에 대한 걱정 마십시오 전체 article

CREATE PROCEDURE [dbo].[get_crossdatabase_dependencies] AS 

SET NOCOUNT ON; 

CREATE TABLE #databases(
    database_id int, 
    database_name sysname 
); 

INSERT INTO #databases(database_id, database_name) 
SELECT database_id, [name] 
FROM sys.databases 
WHERE 1 = 1 
    AND [state] <> 6 /* ignore offline DBs */ 
    AND database_id > 4; /* ignore system DBs */ 

DECLARE 
    @database_id int, 
    @database_name sysname, 
    @sql varchar(max); 

CREATE TABLE #dependencies(
    referencing_database varchar(max), 
    referencing_schema varchar(max), 
    referencing_object_name varchar(max), 
    referenced_server varchar(max), 
    referenced_database varchar(max), 
    referenced_schema varchar(max), 
    referenced_object_name varchar(max) 
); 

WHILE (SELECT COUNT(*) FROM #databases) > 0 BEGIN 
    SELECT TOP 1 @database_id = database_id, 
       @database_name = database_name 
    FROM #databases; 

    SET @sql = 'INSERT INTO #dependencies select 
     DB_NAME(' + convert(varchar,@database_id) + '), 
     OBJECT_SCHEMA_NAME(referencing_id,' 
      + convert(varchar,@database_id) +'), 
     OBJECT_NAME(referencing_id,' + convert(varchar,@database_id) + '), 
     referenced_server_name, 
     ISNULL(referenced_database_name, db_name(' 
      + convert(varchar,@database_id) + ')), 
     referenced_schema_name, 
     referenced_entity_name 
    FROM ' + quotename(@database_name) + '.sys.sql_expression_dependencies'; 

    EXEC(@sql); 

    DELETE FROM #databases WHERE database_id = @database_id; 
END; 

SET NOCOUNT OFF; 

SELECT * FROM #dependencies; 
+1

데이터베이스가 오프라인 상태 인 경우 여전히 액세스하려고하므로 오류가 발생합니다. –

+0

좋은 점은 오프라인 데이터베이스를 무시하기 위해'WHERE' 필터에 행을 추가했기 때문입니다^_ ^ – Oreo

관련 문제