2014-07-25 2 views
1

다음 이름 지정 규칙 (table_20140618, table_20140623 등)으로 여러 테이블을 생성하는 기존 응용 프로그램이 있습니다. 프로그램 실행 날짜입니다. 데이터베이스를 정리하고 일부 테이블을 삭제하려고합니다.서로 다른 날짜의 다른 테이블을 순환합니다.

각 테이블에는 DateStarted와 DateFinished라는 두 개의 필드가 있습니다. DateStarted 값이 있고 DateFinished가 null이 아닌 테이블을 선택한 다음 드롭합니다.

순간에 나는 'table_' 등로 시작하는 모든 테이블을 선택하려면 다음 쿼리를 사용하고 있습니다 : 나는 내에서 검색하여 모든 테이블을 함께하는 방법을 잘 모르겠습니다

Select (TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE' 
AND TABLE_NAME LIKE 'table_%'; 

을 자신의 전지. 코드를 통해이 작업을 수행 할 수는 있지만 데이터베이스에 여러 차례 히트가 있어야합니다. 어떤 아이디어?

+1

테이블이므로 모든 * DateStarted 필드에 값이 있어야하고 * 모든 * DateFinished가 null이라는 것을 의미합니까? 또는 한 번에 하나의 행에 조건이 일치하거나 어떤 행에 두 조건이 일치하는 한 조건이 일치합니까? – Kahn

+0

@Kahn Hi Kahn. DateStarted는 항상 존재해야합니다. DateFinished는 null이거나 값을 가질 수 있습니다. – alwaysVBNET

+1

아래 답변. 필터 요구 사항을 충족시키기 위해 스크립트를 수정할 수 있어야합니다. 하지만 그렇지 않다면 나중에 물어 보겠습니다. :) – Kahn

답변

1

위의 첫 번째 의견을 작성한 후이를 작성했지만 사양에 맞게 코드를 변경할 수 있어야합니다. 기본적으로 이것은 동적 SQL을 사용하여 필터 및 조건을 기반으로 명령을 생성합니다. 따라서 SELECT @SQL = ... 부분에서 원하는 조건을 사용하여 날짜를 확인한 다음 조건이 충족 될 때 테이블 이름을 추가 할 수 있습니다.

스크립트는 tablenames 및 drop 명령을 사용하여 목록을 반환하므로 수행하기 전에 수행중인 작업을 확인할 수 있습니다. 그러나 거기에서 드롭 명령 목록을 복사하고 원하는 경우 실행할 수 있습니다.

IF OBJECT_ID('tempdb..#TABLES') IS NOT NULL 
    DROP TABLE #TABLES 

CREATE TABLE #TABLES (ROWNMBER INT IDENTITY(1,1), TABLENAME VARCHAR(256) COLLATE DATABASE_DEFAULT) 

/* 
-- Old code to fetch ALL tables with specified name 
INSERT INTO #TABLES 
SELECT name 
FROM sys.tables 
WHERE name LIKE 'table[_]%' 
*/ 

-- Updated code to fetch only those tables which contain the DateStarted and DateFinished columns 
INSERT INTO #TABLES 
SELECT TAB.name 
FROM sys.tables TAB 
LEFT JOIN sys.columns C1 on C1.object_id = TAB.object_id 
    AND C1.name = 'DateStarted' 
LEFT JOIN sys.columns C2 on C2.object_id = TAB.object_id 
    AND C2.name = 'DateFinished' 
WHERE TAB.name LIKE 'table[_]%' 
AND C1.name IS NOT NULL AND C2.name IS NOT NULL 

IF OBJECT_ID('tempdb..#DROPPABLE_TABLES') IS NOT NULL 
    DROP TABLE #DROPPABLE_TABLES 

CREATE TABLE #DROPPABLE_TABLES (TABLENAME VARCHAR(256) COLLATE DATABASE_DEFAULT) 

DECLARE @ROW_NOW INT, @ROW_MAX INT, @SQL VARCHAR(MAX), @TABLENAME VARCHAR(256) 
SELECT @ROW_NOW = MIN(ROWNMBER), @ROW_MAX = MAX(ROWNMBER) FROM #TABLES 

WHILE @ROW_NOW <= @ROW_MAX 
BEGIN 
    SELECT @TABLENAME = TABLENAME FROM #TABLES WHERE ROWNMBER = @ROW_NOW 

    SELECT @SQL = 
'IF (SELECT COUNT(*) FROM '[email protected]+' WHERE DateStarted IS NOT NULL) > 0 
    AND (SELECT COUNT(*) FROM '[email protected]+' WHERE DateFinished IS NOT NULL) > 0 
SELECT '''[email protected]+'''' 

    INSERT INTO #DROPPABLE_TABLES 
    EXEC(@SQL) 

    SET @ROW_NOW = @ROW_NOW+1 
END 

SELECT *, 'DROP TABLE '+TABLENAME DROPCOMMAND FROM #DROPPABLE_TABLES 

편집 :는 귀하의 의견에 따라 경찰, 그것은 모든 같은 테이블이 그 열이 보인다 . 다음 스크립트를 사용하여 해당 테이블과 누락 된 열을 식별 할 수 있으므로 더 자세히 확인할 수 있습니다. 그리고 동일한 아이디어를 사용하여 첫 번째 쿼리의 결과를 필터링하여 해당 열이있는 테이블에만 집계 할 수 있습니다.

SELECT TAB.name TABLENAME 
    , CASE WHEN C1.name IS NULL THEN 'Missing' ELSE '' END DateStarted_COL 
    , CASE WHEN C2.name IS NULL THEN 'Missing' ELSE '' END DateFinished_COL 
FROM sys.tables TAB 
LEFT JOIN sys.columns C1 on C1.object_id = TAB.object_id 
    AND C1.name = 'DateStarted' 
LEFT JOIN sys.columns C2 on C2.object_id = TAB.object_id 
    AND C2.name = 'DateFinished' 
WHERE TAB.name LIKE 'table[_]%' 
AND (C1.name IS NULL 
    OR C2.name IS NULL) 
+0

잘 모르겠지만 오류가 발생했습니다. (영향을받은 4 행) 메시지, 수준 16, 상태 1, 줄 1 'DateStarted'열 이름이 잘못되었습니다. msg 207, 수준 16, 상태 1, 줄 2 'DateFinished'열 이름이 잘못되었습니다. msg 207, 수준 16, 상태 1, 줄 1 'DateStarted'열 이름이 잘못되었습니다. msg 207, 수준 16, 상태 1, 줄 2 'DateFinished'열 이름이 잘못되었습니다. msg 207, 수준 16, 상태 1, 줄 1 'DateStarted'열 이름이 잘못되었습니다. msg 207, 수준 16, 상태 1, 줄 2 'DateFinished'열 이름이 잘못되었습니다. (0 행 영향) (0 행 영향) – alwaysVBNET

+0

위의 응답을 편집했습니다. – Kahn

+0

화려한 대답. – alwaysVBNET

관련 문제