다른 곳에서 전체 백업된 SQL을 받아 데이터베이스를 생성했는데, 생성했더니, 데이터베이스의 Data Collate가 "Latin1_General_CI_AS"로 설정되어 있었다. 그래서 간신히 데이터베이스의 설정 값을 바꾸어 "Korean_Wansung_CI_AS"으로 바꾸긴 했다. 그런데 Query를 실행하니까, 웬걸...컬럼들은 여전히 "Latin1_General_CI_AS" 로 되어 있었고, 새로 만든 테이블 내의 값들과 비교하려는데 자꾸 다음과 같은 에러메시지를 뱉어됐다.

Cannot resolve the collation conflict between "Korean_Wansung_CI_AS" and "Latin1_General_CI_AS" in the equal to operation.

데이블 디자이너, 그러니까, 테이블 수정에 들어가 varchar 컬럼마다 데이터 정렬(Data Collate) 값을 바꾸면 되긴 하는데, 이 많은 테이블의 또, 그 컬럼들에 들어가 수정하려니 깝깝했다.

그래서 구글을 통해서 이런 저런 검색한 결과, stackOverflow에서 찾았다.

https://stackoverflow.com/questions/18122773/change-collations-of-all-columns-of-all-tables-in-sql-server

 

Change collations of all columns of all tables in SQL Server

I imported a database with some data to compare with another database. The target database has collation Latin1_General_CI_AS and the source database has SQL_Latin1_General_CP1_CI_AS. I did change ...

stackoverflow.com

아래의 코드 값에서 @collate값만 Korean_Wansung_CI_AS로 변경하고, 수정할 데이터베이스의 쿼리창을 열고 실행했다.

DECLARE @collate nvarchar(100);
DECLARE @table nvarchar(255);
DECLARE @column_name nvarchar(255);
DECLARE @column_id int;
DECLARE @data_type nvarchar(255);
DECLARE @max_length int;
DECLARE @row_id int;
DECLARE @sql nvarchar(max);
DECLARE @sql_column nvarchar(max);

SET @collate = 'Korean_Wansung_CI_AS';

DECLARE local_table_cursor CURSOR FOR

SELECT [name]
FROM sysobjects
WHERE OBJECTPROPERTY(id, N'IsUserTable') = 1

OPEN local_table_cursor
FETCH NEXT FROM local_table_cursor
INTO @table

WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE local_change_cursor CURSOR FOR

    SELECT ROW_NUMBER() OVER (ORDER BY c.column_id) AS row_id
        , c.name column_name
        , t.Name data_type
        , c.max_length
        , c.column_id
    FROM sys.columns c
    JOIN sys.types t ON c.system_type_id = t.system_type_id
    LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
    LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
    WHERE c.object_id = OBJECT_ID(@table)
    ORDER BY c.column_id

    OPEN local_change_cursor
    FETCH NEXT FROM local_change_cursor
    INTO @row_id, @column_name, @data_type, @max_length, @column_id

    WHILE @@FETCH_STATUS = 0
    BEGIN

        IF (@max_length = -1) OR (@max_length > 4000) SET @max_length = 4000;

        IF (@data_type LIKE '%char%')
        BEGIN TRY
            SET @sql = 'ALTER TABLE ' + @table + ' ALTER COLUMN ' + @column_name + ' ' + @data_type + '(' + CAST(@max_length AS nvarchar(100)) + ') COLLATE ' + @collate
            PRINT @sql
            EXEC sp_executesql @sql
        END TRY
        BEGIN CATCH
          PRINT 'ERROR: Some index or constraint rely on the column' + @column_name + '. No conversion possible.'
          PRINT @sql
        END CATCH

        FETCH NEXT FROM local_change_cursor
        INTO @row_id, @column_name, @data_type, @max_length, @column_id

    END

    CLOSE local_change_cursor
    DEALLOCATE local_change_cursor

    FETCH NEXT FROM local_table_cursor
    INTO @table

END

CLOSE local_table_cursor
DEALLOCATE local_table_cursor

GO

지금 모든 데이터베이스의 모든 테이블의 컬럼들을 한번에 수정할 수 있었다.

다행다행...

728x90

현재 개인 개발 도구를 이용해서 작업 중인데, 네트워크 IP가 미묘하게 겹쳐 업무를 할 때마다 Lan 선을 뽑았다 꼈다를 반복해왔다.

개발 PC에 랜카드를 두개 붙여서 한 쪽은 192.168.30.200 으로 설정해서, 인터넷이나 버전관리 서버에 접속해서 Commit을 했고, 다른 한쪽에는 192.168.0.105 으로 설정한 뒤, Lab 실에 있는 장비와 연결을 했다.

인터넷 하면서 Lab 실 장비를 건드릴 때는 문제가 없는데, 딱! 버전관리 서버를 손대자 문제가 터져나갔다.
그 이유가 192.168.0.x 대역을 버전관리 서버와 Lab실이 동시에 이용해서 이다.
만일 버전관리 서버와 연결하고 싶으면 Lab 실과 연결된 네트워크 랜선을 떼어야 하고,
다시 Lab 장비를 손대려면 다시 붙여야 한다. 만일 Lab 실 장비 손 보다가, 소스 수정할 내용을 Commit을 하고 싶으면 다시 뗀것을 붙여야 했다.

한 두번은 하겠는데, Commit 되는 횟수가 늘어나면 늘어날 수록 점점 귀차니즘이 돌발했다.

그래서 방법을 바꿨다. 그래서 route 라는 명령을 찾게 되었다.

route는 현재 네트워크를 호출할 때 어디로 연결해서 처리할지를 나타내고 수정하는 도구다.
먼저 관리자 권한으로 터미널(관리자)를 연다.

그리고 다음과 같이 명령을 입력하면 현재 설정된 라우팅 정보가 보인다.

저 라우팅 테이블의 내용만 보면, 0.0.0.0 즉 모든 연결은 192.168.30.200 인터페이스에 있는 192.168.30.1 게이트웨이로 보낸다는 의미다. 그리고 192.168.0.0 즉 192.168.0.x 로 된 모든 연결은 192.168.0.105 인터페이스로 보낸다는 의미다.

이걸 보고 해석을 하면, 192.168.30.63  하면, 192.168.30.200 인터페이스를 통해 패킷을 보내고, 192.168.0.3 하면, 192.168.0.105 인터페이스를 통해 패킷을 보낸다.

문제는 192.168.0.2 를 했을 때도, 192.168.0.105를 통해 내보낸다.
내 버전관리 서버는 192.168.30.200을 통해서 VPN을 거쳐 접속을 해야 하는데도 말이다.

그래서 방법을 찾은게 route 명령을 통해 아래와 같이 입력하는 것이다.

route add 192.168.0.2 mask 255.255.255.255 192.168.30.200 -p

192.168.0.2 의 연결에서 Subnet mask를 255.255.255.255를 하면, 딱 저 IP를 입력할 때, 192.168.30.200 인터페이스로 패킷을 보내라는 명령이다. 일단 Subnet mask 부분에서 이해의 폭을 너무 많이 요구하긴 하지만, 최소한 맨 앞의 값과 255.255.255.255 가 붙으면 1개의 IP 라고 읽자.
192.168.0.3 이나 192.168.0.100 같은 경우에는 라우팅 테이블 상에 있는 192.168.0.0 / 255.255.255.0 에 걸려 192.168.0.105 인터페이스로 패킷을 보내지만,
192.168.0.2 는 192.168.0.2 / 255.255.255.255 에 걸려서 192.168.30.200 인터페이스로 패킷을 보낸다고 이해하면 된다.
여기서 인터페이스 라는게 랜카드를 의미하고, 그 랜카드에 설정된 IP 주소라고 읽으면 된다.

맨 마지막의 -p는 영구 연결이라고 해서 네트워크가 리셋되도 일단 살아 있게 만들어 준거다. 없으면 나중에 네트워크 리셋되는 순간 위의 명령만 다시 넣어주면 된다.

나중에 vpn을 통해 이용해야 할 서버의 IP 192.168.0.88 라는게 생기고, 지금과 같이 하고 싶다면,  위의 명령을 이용해서 만들어 줄 수 있다.

route add 192.168.0.88 mask 255.255.255.255 192.168.30.200 -p

 

 

728x90

2022년이니까 햇수로는 2년, 만으로는 1년 반정도 전에 구매.

당시에는 나름 뭐 내적 갈등과 합리화를 통해서 받아드리긴 했는데,
가격이 참 살벌하네;;;;;

딱 10,000 Km 찍어보고 다시 정리해보자

728x90

이게 지금 내가 가진 제품인지 더 확인을 해봐야 겠지만...

도면이 Raddit에 있어서 한번 퍼왔다.
https://www.reddit.com/r/overclocking/comments/r2um0w/default_thermal_pad_thickness_for_sapphire_radeon/

메모리 쪽이 0.75 mm 이고,
파워 쪽이 1.0 mm 인 것 같다.

0.15 쪽은 써멀 구리스로 하면 되니까..

내일 써멀구리스와 써멀패드를 모두 모아와서 분해해 봐야겠다.

728x90

1인 개발자나 스스로 후원자 하면서 세월아 내월아 해도 상관없는 경우를 제외하고, 일감을 받아 업무를 수행하고 돈을 받아가는 형태로 업무를 진행하고 있다면 좀 고려해주었으면 하는 게 있다.


바로 신뢰도다. 
조금은 많이 뭉그뜨려서 표현한 부분이긴 한데, 자기 자신의 속도에 대한 이해도와 현재 업무에 대한 전체적인 파악 및 장악력 같은 내용을 의미한다.
예를 들면, 현재 프로젝트에서 특정 모듈을 개발하는 업무를 받았다고 치자. 여기서 PM 혹은 PL은 얼마나의 시간이 걸릴지를 묻곤 한다. 여기서 그 답을 줄 수 있느냐 없느냐는 부분이다. 물론 성격에 따라 정확한 수치가 아니면 제시할 수 없다고 하는 완벽주의(?)를 가진 분도 있긴 하지만, 그런 부분을 차치하고, 대략적인 수치를 떠올릴 수 있냐 없느냐다. 
이런 대략적인 수치를 뽑으려면 2가지가 요구된다. 


그 하나가 자신의 개발 속도다. 
특정 과제를 해결하는 데 걸리는데 보통 며칠이 걸리는지, 그 과제의 난이도는 어떤지 등에 대해서 기준점을 확실히 하는 것이다. 그래서 특정 과제, 유사 과제 등이 제시되었을 때 어느 정도의 기간 내에 개발할 수 있는지를 곱셈이든, 덧셈이든 해서 값을 도출할 수 있게 된다.

그리고 다른 하나가 주어진 과제에 대한 장악력이다. 
왜 내가 이 부분을 만들어야 하고 -오해하지 말아야 할 부분이 할지 말지를 알기 위한 게 아니다. 반드시 해야 한다. 다만 이렇게 만들어지는 게 어떻게 이용되고 활용되어야 하는지를 의미한다. - , 전체 프로젝트에 어느 부분에 해당하고 어느 정도의 영향력이 있는지 등을 이해하는 능력이다. 하지만 이런 능력은 해당 업무 도메인에 대한 경험치와 비례하기 때문에, 초보 개발자에게 요구하기엔 무리가 있긴 하다. 하지만 이 부분에 대한 대응 가능 여부에서  자신이 초급인지 중급인지 고급인지를 나누게 된다. 

이 업계에서 20여 년간 지내보면서 다양한 동료와 일을 해보면서 느낀 점은 저 부분에 대해서 고민하는지 안하고 피동적으로만 일하는지에 따라 다른 길로 나아간다. 때로는 상급자로, 때로는 금전적 보상으로, 때로는 인정으로 보상을 받으며 일하는지, 아니면 그저 잠깐 인력 지원 레벨에서 끝나 이곳 저곳을 전전하다 결국 적응 실패로 다른 직업으로 전환하거나, 마지못해 일하는 모습만으로 무시 혹은 평가절하 신세를 면치 못하는 모습에 실망하는 모습을 여럿 본 것 같다.

시킨 것만 하고, 미련하게 앞서 생각하다 깨지고 나댄다고 혼날 바엔 조용히 할 일만 하고 따박 따박 월급 받으면서 사는게 제일이야.. 라고 자신있게 말하는 분도 보지만, 결국 활동시기가 저무는 40대 즈음 자신이 해온 일을 쭉 돌아보고 나면 대개는 후회한다고 생각한다.

만일 아직 20대고 30대라면 저 부분에 대해서 고민해보자.
상급자가 겁나게 까칠하거나, 되먹지 않다면 굳이 나대가며 할 필요까지는 없지만, 스스로 계산해보고, 정말 그런지 안그런지를 조용하게 검증해보면서 기준을 잘 세워본다면 상급자로 올라가거나 다른 곳으로 이직하면서 새롭게 적용할 때, 준비된 개발자로 거듭나지 않을까 생각한다.

728x90

Jenkins를 이용해 자동으로 빌드하고, 빌드한 결과물은 Zip으로 압축하여 제공한다.
여기서 빌드 결과물 파일에는 BUILD_NUMBER 값을 이용해 파일명을 만들고 있다.

SET FILENAME=MYSELF_%BUILD_NUMBER%.zip

문제는 저 BUILD_NUMBER 부분인데, 이게 1부터 시작해서 빌드 될 때마다 자동으로 1씩 더해지는 값이다.

그러다보니, File Sort를 해보면, 아래 처럼 될 때가 있다.

MYSELF_1.zip
MYSELF_10.zip
MYSELF_11.zip
MYSELF_2.zip
MYSELF_3.zip
MYSELF_4.zip
MYSELF_5.zip
MYSELF_6.zip
MYSELF_7.zip
MYSELF_8.zip
MYSELF_9.zip

요즘은 운영체제가 좋아지기도 했고, 파일관리도구들도 지능적이여서, 저 숫자부분만 떼서 Sort를 해주기도 하지만, 기본적인 String Sort로 하게되면 저렇게 된다.

방법은 저 파일명의 숫자부분 앞에 "0"을 채우면 된다.

그러니까...

MYSELF_0001.zip
MYSELF_0002.zip
MYSELF_0003.zip
MYSELF_0004.zip
MYSELF_0005.zip
MYSELF_0006.zip
MYSELF_0007.zip
MYSELF_0008.zip
MYSELF_0009.zip
MYSELF_0010.zip
MYSELF_0011.zip

위와 같이 만들 수 있다.

이를 위해서는 Jenkins 빌드 후 파일명 만들 때 다음과 같이 만들면 된다.

SET PADDED_BUILD_NUMBER=000%BUILD_NUMBER%
SET PADDED_BUILD_NUMBER=%PADDED_BUILD_NUMBER:~-4%

SET FILENAME=MYSELF_%PADDED_BUILD_NUMBER%.zip

굳이 설명하자면,

1번째 줄에서는 BUILD_NUMBER라는 값 앞에 "000"을 붙인다.
1이면 0001이든, 951이면 000951 같이 된다.

2번째 줄에서는 뒤에서 4글자만 뽑는다.
0001 이면 0001, 000951 이면 0951 식으로 4글자만 뺀다.

그리고 나머지 줄에서는 그렇게 만든 4글자짜리 BUILD_NUMBER를 이용해, 파일명을 만든 것이다.

핵심은....

:~-4

이다.

%{환경변수 이름}:~{+ 앞에서부터, - 뒤에서 부터}{추출할 갯수}%

 

728x90

Windows 10 부터 미디어 작성도구를 제공해서, USB에 자신의 설치용 Windows을 쉽게 만들수 있다.
다만, 이렇게 만들 때, 다양한 버전이 이 안에 들어가다 보니, 설치 중 Profesional 버전을 설치하고 싶을 때 골라서 설치가 안된다. 특히 설치 대상 PC가 OEM PC이고, 바이오스 상에 Windows 라이선스가 박혀 있는데, 그것도 Home Edition인 경우 매우 곤란했다. 쭉 설치하다보면 Home Edition으로 설치되고 끝. 게다가, 요즘 Windows 11 Home의 경우 Microsoft 계정이 없으면 설치도 안되기 때문에, Profesional로 설치하고 싶은데 매번 아무런 질문도 없이 진행되니...

그러나 구글로 찾아보니.. 나오긴 한다.

1. 설치용 USB를 만든다.
그냥 만든다. Microsoft 사이트에 들어가 Media Creation Tool을 받아서 USB 꼽고 만들어 달라고 하면 자동으로 USB에 설치 미디어를 만들어 준다. 이를 설치할 PC에 연결한 뒤 설치하면 잘 진행된다.
물론 여기에 조금 더 작업을 가미해야 한다.

2. ei.cfg 파일을 {설치용 USB 드라이브명}:\sources 폴더에 만들기.
USB가 만들어지면 드라이브가 잡히는데, 아마도 E:\나 F:\ 정도인데,
E:\sources 혹은 F:\Sources 폴더 안에 Text 파일(노트패드 등으로 작성)을 하나 만든다.
만들 때 파일명을 ei.cfg로 하고 만든다.

3. ei.cfg 안에 다음 내용을 넣는다.

[EditionID]
Professional

[Channel]
Volume 

[VL]
1

자세한 설명은 아래 링크를 통해 내용을 확인하도록 한다.
https://learn.microsoft.com/ko-kr/windows-hardware/manufacture/desktop/windows-setup-edition-configuration-and-product-id-files--eicfg-and-pidtxt?view=windows-11

 

Windows 설치 프로그램 버전 구성 및 제품 ID 파일(EI.cfg 및 PID.txt)

Windows 설치 프로그램 버전 구성 및 제품 ID 파일(EI.cfg 및 PID.txt) 아티클 05/30/2023 기여자 5명 피드백 이 문서의 내용 --> 선택적으로 버전 구성(EI.cfg) 및 제품 ID(PID.txt) 파일을 사용하여 Windows 설치 중

learn.microsoft.com

 

저장이 끝나면 이제 이 USB를 이용해 Windows 11을 설치하면 된다.

 

728x90

2년전 (2021년 11월 경)에 레노버 노트북인 T14Gen2 라이젠 에디션을 구매했다.
잘 쓰고 있는데, 간혹 외부에 나갈 때, 회의 할 때 노트북을 들고 나가려면 매번 여러 포트들에 연결된 장비들을
해제하고 정리해야 했다.

전원으로 사용되는 USB-C 포트.
포트 확장으로 이용되는 또 다른 USB-C 포트.
4K 해상도의 큰 모니터 연결용 HDMI 포트.
키보드, 마우스 USB-A 포트,
유선랜을 위한 RJ-45 포트 ...등등.

한 두번이야 뺐다가 다시 끼면 된다고 하지만, 회의 2번 정도 하면,
자연스럽게 노트북 보다는 다이어리로 적고, 그것을 다시 PC로 옮겨 적곤 했다.

물론 USB-C 형태의 멀티 포트 지원하는 제품들을 사용해서
근래 유행하는 USB-C 기반의 Docking Station이 있고, 그것을 이용하면, 전원부터 모니터, 랜선까지
다양한 기기를 한번에 뺐다가 다시 낄 수 있긴 하다.
그런데, 개인적인 생각에는 Intel의 썬더볼트 기반의 구조가 아니면, 대역폭의 한계가
알게 모르게 보이게 됐고.. 더욱이 T14의 경우 다른 USB-C 포트는 주변이 이상하게 생긴 부분이 있다.

USB-C가 두개가 있는데, 하나는 전원단자를 거의 담당하고, 다른 하나는 뭔가 이상한 포트와 한셋트 처럼 되어 있었다.

뭔가.. 이용할 포인트가 없었을까? 해서... 레노버 공홈에서 Docking Station을 검색하는데 이젠 USB-C 기반의 Docking Station으로 밖에는 없었다. 예전 노트북들의 옵션과 같은 진짜 Docking Station이 아니라, USB-C 기반의 허브로 된 Docking Station이 전부였다. 불가능은 아니지만 대역폭 문제와 의문의 단자 부분의 활용이 아깝다는 생각에 고민에 빠졌다.

그러다가.. 우연히 E-Bay에서 아래와 같은 Docking Station을 발견했다.
https://www.ebay.com/sch/i.html?_from=R40&_trksid=p4432023.m570.l1311&_nkw=lenovo+40aj0135us&_sacat=0

 

lenovo 40aj0135us for sale | eBay

유효한 가격 범위를 입력해 주세요

www.ebay.com

다 좋은데.. 문제는 호환성.

T14Gen2가 지원되는지 안되는지에 대한 문구를 어디서 찾아보기 힘들었고, 과연 연결이 제대로 되는지 조차 알길이 없었다. 외국어를 잘하고, 뭔가 자신감 뿜뿜이면 Reddit 같은데 질문도 올려보고 고민을 다양하게 해보겠지만, 소심자로는 도무지 용기가 나지 않았다. 물론 가격이 3~40불이라고 적혀 있어 계산해보니 5~6만원 정도라... 질러 볼까 했는데, 배송비 등을 보니까(물론 무료도 있지만, 대개는 대행사가 있어야만 가능) 10만원 언저리.

고민하다가 Amazon에서 구매를 했다.
https://www.amazon.com/s?k=40AJ0135US&ref=nb_sb_noss

이베이가 저렵한 것 같지만, 배송비 장난이나, 국내 배송 불가가 은근히 많고, 제품이 중고인데, New라고 하는 곳도 있고..애매해서였다.

배송까지는 대략 1주걸린듯.

제품은 도킹스테이션과 아답터가 있는데, 이 아답터는 도킹스테이션과 연결되어 노트북에 전원을 공급한다.
그리고 도킹스테이션과 노트북이 연결하는게 좀 재미있는데, 왼쪽 슬라이드 부분이 노트북과 연결되지 않으면 꿈쩍도 하지 않는데, 처음에 그냥 밀어봤는데, 뭐가 잠긴듯 꿈쩍하지 않는 것이였다. 그래서 열쇠가 잠겨서 인가? 싶었는데, 그것도 아니였다. 처음에 연결이 잘 안되서 호환이 안되는줄 알아... 돈 날렸구나.. 했다.

노트북이 놓이는 자리 쪽에 눌리는 스위치 같은 부분이 여러개 있는데, 노트북이 잘 놓으면 그 부분이 모두 눌리면서 자연스럽게 슬라이드시켜 노트북과 연결하는 구조였다. 저 도킹판 위에 노트북을 이리저리(상하, 좌우)로 조금씩 이동시키다보면 아래로 조금 내려가면서 뭔가 체결되는 느낌이 있다. 그 시점에 왼쪽의 슬라이드를 밀어 노트북과 연결하면 된다.

모델명은 40AJ0135US 이여서, 대략 검색으로 충분히 찾을 수 있을 것이다.

다른 것 모르겠지만, 자신의 Lenovo 노트북 왼편의 포트 중 USB-C 포트가 두개이고, 다른 한쪽의 USB-C 포트가 이상하게 생긴 포트로 둘러싸인 구조라면 대부분 호환될 것 같다. (하지만 검색해서 나오지 않는다면 용기가 좀 필요할 듯)

지금은 매우 만족해서 쓰고 있고, 기능이나 성능 그 어떤 부분에서도 불만이 없다.

진즉 알았으면 좋았겠지만, 늦게 산만큼 가격은 저렴해진 부분도 있어 현재로는 불만 0 상태다.

728x90

+ Recent posts

728x90