재우니 개발자 블로그

 

 

INFORMATION_SCHEMA.COLUMNSSTRING_AGG 함수를 활용하면, 테이블의 컬럼이 추가되거나 변경될 때마다 일일이 쿼리를 수정할 필요 없이 동적으로 쿼리를 생성하고 실행하는 강력한 Stored Procedure(SP)를 만들 수 있습니다.

 

목적(문자열 추출 또는 실제 실행)에 맞게, 테이블명과 타겟/소스 데이터베이스명을 파라미터로 받아 유연하게 동작하는 SP 스크립트입니다.

 


🛠️ 동적 데이터 복사 Stored Procedure 스크립트

 

이 SP는 @IsExecute 파라미터 값에 따라 단순히 쿼리를 텍스트로 출력(추출)할 수도 있고, 즉시 실행할 수도 있도록 설계되었습니다.

 

CREATE OR ALTER PROCEDURE usp_CopyTableData_Dynamic
    @SourceDB NVARCHAR(128),       -- 데이터를 가져올 Source DB명 (예: DB_INTRAWorkingHour)
    @TargetDB NVARCHAR(128),       -- 데이터를 넣을 Target DB명 (예: NpmUnivEsEW)
    @TableName NVARCHAR(128),      -- 대상 테이블명 (예: UNIV_WORK_ManagerConfig)
    @IsExecute BIT = 0             -- 0: 쿼리 문자열만 추출(PRINT 및 SELECT), 1: 쿼리 실제 실행
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @ColumnList NVARCHAR(MAX);
    DECLARE @SQL NVARCHAR(MAX) = N'';
    DECLARE @ColumnQuery NVARCHAR(MAX);
    DECLARE @IdentityCheckQuery NVARCHAR(MAX);
    DECLARE @HasIdentity BIT = 0;

    BEGIN TRY
        -- 1. 컬럼명 추출
        SET @ColumnQuery = N'
            SELECT @Cols = STRING_AGG(QUOTENAME(COLUMN_NAME), '', '') 
            FROM ' + QUOTENAME(@TargetDB) + N'.INFORMATION_SCHEMA.COLUMNS 
            WHERE TABLE_NAME = @Tbl';

        EXEC sp_executesql 
            @ColumnQuery, 
            N'@Tbl NVARCHAR(128), @Cols NVARCHAR(MAX) OUTPUT', 
            @TableName, 
            @ColumnList OUTPUT;

        IF @ColumnList IS NULL
        BEGIN
            PRINT 'Error: [' + @TargetDB + '] 데이터베이스에 [' + @TableName + '] 테이블이 존재하지 않거나 컬럼이 없습니다.';
            RETURN;
        END

        -- 2. 대상 테이블에 IDENTITY 컬럼이 존재하는지 확인
        SET @IdentityCheckQuery = N'
            SELECT @HasId = CASE WHEN EXISTS (
                SELECT 1 
                FROM ' + QUOTENAME(@TargetDB) + N'.sys.identity_columns 
                WHERE object_id = OBJECT_ID(''' + QUOTENAME(@TargetDB) + N'.dbo.' + QUOTENAME(@TableName) + N''')
            ) THEN 1 ELSE 0 END';
        
        EXEC sp_executesql
            @IdentityCheckQuery,
            N'@HasId BIT OUTPUT',
            @HasIdentity OUTPUT;

        -- 3. INSERT 쿼리 동적 생성 (IDENTITY 존재 여부에 따라 분기)
        IF @HasIdentity = 1
        BEGIN
            SET @SQL = @SQL + N'SET IDENTITY_INSERT ' + QUOTENAME(@TargetDB) + N'.dbo.' + QUOTENAME(@TableName) + N' ON;' + CHAR(13) + CHAR(10);
        END

        SET @SQL = @SQL + N'INSERT INTO ' + QUOTENAME(@TargetDB) + N'.dbo.' + QUOTENAME(@TableName) + N' (' + @ColumnList + N')' + CHAR(13) + CHAR(10) +
                   N'SELECT ' + @ColumnList + CHAR(13) + CHAR(10) +
                   N'FROM ' + QUOTENAME(@SourceDB) + N'.dbo.' + QUOTENAME(@TableName) + N';' + CHAR(13) + CHAR(10);

        IF @HasIdentity = 1
        BEGIN
            SET @SQL = @SQL + N'SET IDENTITY_INSERT ' + QUOTENAME(@TargetDB) + N'.dbo.' + QUOTENAME(@TableName) + N' OFF;';
        END

        -- 4. 실행 또는 문자열 추출
        IF @IsExecute = 1
        BEGIN
            PRINT 'Executing Script for Table: ' + @TableName;
            EXEC sp_executesql @SQL;
            PRINT 'Execute Completed Successfully.';
        END
        ELSE
        BEGIN
            PRINT '--- [Generated Script] ---';
            PRINT @SQL;
            SELECT @SQL AS GeneratedSQL;
        END
    END TRY
    BEGIN CATCH
        -- 에러 발생 시 처리
        PRINT 'Error occurred during execution.';
        PRINT 'Error Message: ' + ERROR_MESSAGE();
    END CATCH
END
GO

 

 


💡 SP 실행 및 활용 방법

SP를 생성하신 후, 아래와 같이 상황에 맞게 파라미터를 변경하여 호출하시면 됩니다.

 

1. 쿼리 문자열만 추출 (테스트 및 확인용)

 

안전하게 쿼리가 어떻게 생성되는지 눈으로 확인하거나 복사하고 싶을 때 사용합니다. (@IsExecute = 0)

EXEC usp_CopyTableData_Dynamic 
    @SourceDB = 'DB_INTRAWorkingHour', 
    @TargetDB = 'NpmUnivEsEW', 
    @TableName = 'UNIV_WORK_ManagerConfig', 
    @IsExecute = 0;

 

 

 

2. 쿼리 즉시 실행 (실제 데이터 삽입)

 

생성된 쿼리를 확인했고, 바로 데이터를 밀어 넣고 싶을 때 사용합니다. (@IsExecute = 1)

EXEC usp_CopyTableData_Dynamic 
    @SourceDB = 'DB_INTRAWorkingHour', 
    @TargetDB = 'NpmUnivEsEW', 
    @TableName = 'UNIV_WORK_ManagerConfig', 
    @IsExecute = 1;

 

 


참고로, 테이블 구조를 동적으로 다룰 때는 IDENTITY 속성 유무를 체크하는 것이 필수적입니다. 그렇지 않으면 자동 증가 컬럼이 없는 테이블에서 쿼리가 실패하게 됩니다.

 

해당 테이블에 IDENTITY 컬럼이 존재하는지 시스템 테이블(sys.identity_columns)을 통해 검사하고, 결과에 따라 SET IDENTITY_INSERT ON/OFF 구문을 유동적으로 추가하도록 되어 있습니다.