2014-02-21 5 views
0

표 (A)는 다수의 테이블 (B, C, D ...)와 1-1 관계가 두 열로 정의된다다른 테이블을 가리키는 고아 레코드를 찾으려면 어떻게해야합니까?

  • 다른 테이블 ObjectType(nvarchar(100)) // 이름
  • _Guid(uniqueidentifier) // 다른 테이블에 레코드 ID

또한 모든 테이블에는 IsDeleted(bit) 열이 포함되어 있습니다.

질문 :

방법, C, D, (...) 또는 IsDeleted = 1 세트가 기록에 B에 존재하지 않는 레코드 (A) 그 시점에서 모든 레코드를 나열하는? 다음은 또한 작동하지 않습니다

SELECT ObjectType, _Guid FROM A 
where 
    NOT EXISTS (
     select * from ObjectType where oid = _Guid 
    ) 

:

SELECT ObjectType, _Guid FROM A 
where 
    NOT EXISTS (
     exec('select * from '+ObjectType+' where oid =''' + _Guid + '''') 
    ) 

내가 무엇을 놓치고

다음은 매개 변수 여야합니다 ObjectType 때문에 작동하지 않습니다?

답변

0

이 끔찍한 SQL 아래 작동하는 것 같다 :

DECLARE @A_tmpTable TABLE (
    idx smallint Primary Key IDENTITY(1,1) 
    , ObjectType nvarchar(200) 
    , _Guid nvarchar(100) 
    , Oid nvarchar(100) 
) 
DECLARE @orphanedA_tmpTable TABLE (
    Oid nvarchar(100) 
) 
DECLARE @_objectType nvarchar(200) 
DECLARE @_Guid nvarchar(100) 
DECLARE @_oid nvarchar(100) 
DECLARE @i int, @numrows int 
DECLARE @found bit 

-- populate temp table 
INSERT @A_tmpTable SELECT ObjectType, _Guid, Oid FROM A WHERE IsDeleted = 0 
--SELECT * FROM @A_tmpTable 

-- foreach the @A_tmpTable 
SET @i = 1; 
SET @numrows = (SELECT COUNT(*) FROM @A_tmpTable) 
--SELECT @i, @numrows 
IF @numrows > 0 
    WHILE (@i <= @numrows) 
    BEGIN 
     SET @ObjectType = (SELECT TOP 1 ObjectType FROM @A_tmpTable WHERE idx = @i); 
     SET @_Guid = (SELECT TOP 1 _Guid FROM @A_tmpTable WHERE idx = @i); 
     SET @_oid = (SELECT TOP 1 Oid FROM @A_tmpTable WHERE idx = @i); 

     DECLARE @SQL nvarchar(max) = 'IF EXISTS (SELECT * FROM '[email protected]+' WHERE OID =''' + @_Guid + ''' AND IsDeleted = 0) 
       SET @found = 1; 
      ELSE 
       SET @found = 0; 
      '; 
     -- check if table record exists and save the result in the @found variable 
     exec sp_executesql @SQL, N'@found bit out', @found out 

     IF @found = 0 
      INSERT INTO @orphanedA_tmpTable (Oid) VALUES (@_oid); 


     SET @i = @i + 1 
    END 

SELECT * FROM A WHERE Oid IN (SELECT Oid FROM @orphanedA_tmpTable) 
0

쿼리는 최적화되고 실행되도록 정적으로 알려진 구조를 가져야합니다. 동적 테이블 이름은 사용할 수 없습니다.

가능한 모든 테이블에 가입하십시오.

SELECT * 
FROM A 
LEFT JOIN B ON ... 
LEFT JOIN C ON ... 
LEFT JOIN D ON ... 
WHERE 
(B.IsDeleted IS NULL AND C.IsDeleted IS NULL AND D.IsDeleted IS NULL) 
OR (B.IsDeleted = 1 OR C.IsDeleted = 1 OR D.IsDeleted = 1) 

은 우리뿐만 아니라 ObjectType에 일치해야하기 때문에 내가 정확히 오른쪽 조건을하지 않았다 생각합니다. 내가 고쳐 줄께. 중요한 아이디어는 가능한 모든 테이블에 가입하는 것입니다.