안녕하세요.
SQL을 5년이 넘게 접해왔지만 아직도 초급 수준을 벗어나지 못하고 있네요...
도움을 받을 수 있을까 하여 이곳에 질문을 드립니다.
저희 회사에서 ERP 프로그램을 사용 중입니다.
이 프로그램에는 품목코드와 품목정보가 담긴 ITEM_MASTER라는 테이블이 존재합니다.
그런데 이번에 기존 품목코드 중 일부 (약 1500개) 품목코드가 새로운 품목코드로 변경 되어야 합니다.
예를들면 다음과 같습니다.
기존 품목코드 AAA-11-ABCD-00 를
신규 품목코드 BBB-12-ZZZ 로 모두 변경.
ERP에서 품목코드는 모든 프로세스의 기준이 되는 존재이므로
ITEM_MASTER (품목정보 테이블) 에서만 품목코드를 변경해선 안되고
품목코드가 존재하는 모든 테이블에서 변경사항이 적용 되어야 합니다.
때문에 SP를 만들어서 처리하고자 합니다.
일단은 DB내에 존재하는 모든 테이블에서 ITEM_CODE(품목코드 컬럼명) 컬럼이 존재하는 테이블 목록을 구한 뒤
해당 테이블들의 레코드를 가져와서 기존 품목코드를 신규 품목 코드로 변경해 주려고 합니다.
이 작업을 위해 제가 지금 정리한 내용은 다음과 같습니다.
1. 품목코드 변경 기준 테이블 EX_ITEM_MASTER 생성
이 테이블에는 기존품목코드, 품목명, 단위, 단가, 거래처 ... 등의 정보가 있고 마지막 컬럼에 신규 품목코드 컬럼인
NEW_CODE 컬럼이 존재합니다.
2. 품목코드 변경용 SP제작
-- 일단 ITEM_CODE 컬럼이 존재하는 모든 테이블 목록을 가져온다. --
Select b.name as TableName, a.name as FieldName, a.length
From syscolumns a with(nolock), sysobjects b with(nolock)
Where a.id = b.id and
a.name like 'ITEM_CODE' and
b.type = 'U' and a.length = 13
ORDER BY B.name ASC
위 쿼리를 이용하니 ITEM_CODE 컬럼이 존재하는 모든 테이블을 구할 수 있었습니다.
레코드 결과는 '테이블명', '필드명', '길이' 입니다.
위 레코드 결과를 LOOP 돌리면서 각 테이블마다 ITEM_SCODE 값을 가져온 뒤
만약 해당 품목코드가 EX_ITEM_MASTER(기존/신규 품목코드 정보) 테이블의 레코드와 일치하는 것이 있다면
EX_ITEM_MASTER 테이블의 NEW_CODE 값으로 UPDATE 해줍니다.
이러한 내용을 SP로 제작하여 다음과 같이 수행하고 싶습니다.
EXECUTE sp_exchange_code 'DB명'
sp 뒤에 DB명을 파라미터로 전달하는 이유는 일단 테스트 DB에서 수행해 본 뒤 실제 DB에서
수행하는 것을 구분지어 주기 위함입니다.
SP제작이 완전 생 초보라 어디서부터 손을 대야 할지 모르겠습니다.
비슷한 유형의 SP 정보나 위 조건에 따른 SP 제작을 위해 도움을 받을 수 있을까요?
긴 글 읽어 주셔서 감사합니다.
----------------------------------------------------------------------------------
추가 글
답변 기다리는 동안 제가 만들어 봤는데요...
이게 맞는건지 문제는 없는지 휴... 조언좀 부탁드릴께요.
CREATE procedure [dbo].[sp_exchange_code]
@dbName nchar(8), -- 코드변경 적용할 DB명
AS
Begin
Set NOCOUNT ON
-- 변수 설정 --
DECLARE @TableName nvarchar(32), @FieldName nchar(8), @Length int /* ITEM_CODE 존재하는 테이블 정보 */
, @strSQL nvarchar(4000) /* Query 수행문 저장 변수 */
, @curSQL nvarchar(4000) /* 커서에서 동적쿼리 사용을 위한 변수 */
-- 커서 선언 : ITEM_CODE 컬럼을 가진 모든 테이블 수 만큼 반복 --
Set @curSQL = 'DECLARE CUR_TBL CURSOR FOR '
+ ' Select b.name as TableName, a.name as FieldName, a.length '
+ ' From ' + @dbName + '..syscolumns a with(nolock), ' + @dbName + '..sysobjects b with(nolock) '
+ ' Where a.id = b.id and UPPER(a.name) like ''ITEM_CODE'' and b.type = ''U'' and a.length < 512 '
+ ' ORDER BY B.name ASC'
EXEC sp_executesql @curSQL
-- 커서를 열고 --
OPEN CUR_OS
-- 첫행을 읽어온다. (첫 테이블 정보)
FETCH NEXT FROM CUR_TBL INTO @TableName, @FieldName, @Length
-- 마지막 행까지 반복 (ITEM_CODE 컬럼이 존재하는 테이블 개수만큼 반복)
While @@FETCH_STATUS = 0
BEGIN
-- ITEM_CODE 기존 품목코드를 신규 품목코드로 변경
Set @strSQL = 'update ' + @dbName + '..' + @TableName + ' set ITEM_CODE = CTR.NEW_CODE from'
+ ' EX_ITEM_MASTER CTR '
+ ' where ' + @dbName + '..' + @TableName + '.ITEM_CODE = CTR.ITEM_CODE'
-- 다음 레코드(테이블)로 이동
FETCH NEXT FROM CUR_TBL INTO @TableName, @FieldName, @Length
END
-- 커서를 닫고 종료
CLOSE CUR_TBL
DEALLOCATE CUR_TBL
END
GO
Comment 2
-
catchv
2013.07.08 12:51
-
래리
2013.07.08 16:22
우선 조언 감사드립니다.
글을 올리고 4일이 넘어 댓글이 하나 달렸네요 ^^; 가뭄의 단비 같아요..
말씀하신데로 FK는 정의되어 있지 않습니다.
각 테이블에 ITEM_CODE 컬럼이 존재하는 이유가 현재 파악된 내용으로는 품목코드 값으로 통일 되어 있다는 것입니다.
따라서 FK가 설정되어 있진 않지만 ITEM_CODE라는 컬럼 값을 다른 명목으로 사용하는 경우는 없는 것으로 보입니다.
그렇다면 이 전제하에 위 쿼리로 수정을 했을 경우 문제가 없을까요?
사실 제가 만들어 놓은 쿼리지만 여기 저기서 얻으 정보로 취합해 만든거라 시간 되시면 쿼리분 조언좀 부탁드려요..
감사합니다.
ERP 에 테이블이라면 FK가 정의 되어 있지 않을 것으로 판단됩니다.
하나 우려되는 것이 ITEM_CODE의 이름으로 찾아서 값을 변경해 주는 부분인데요.
각 테이블에 존재하는 ITEM_CODE가 ITEM_MASTER에 존재하는 ITEM_CODE의 값을 참조하는 컬럼인지 검증이
필요할 것 같습니다. ITEM_CODE가 너무 일반적인 이름이라서 다른 의미로 사용되는 컬럼일수도 있을 것 같습니다.