Obsidian?

요즘 글쓰기를 모두 Obsidian 으로 하고 있다.
물론 Evernote나, Notion 과 같은 도구들이 대세이긴 하다. 특히 자체적으로 클라우드로 데이터를 송/수신하고 있어 어느 장비에서 작성해도 어느 장비에서도 동일한 내용을 확인할 수 있는 많은 장점이 있다.

그에 반해 Obsidian의 경우 유료 가입을 하지 않는 경우 데이터 공유같은 훌륭한 기능은 제공하지 않는다.
굳이 공유하고 싶다면, Onedirve나, Google Dirve와 같이 파일 공유 공간에 저장하고,
그 공간을 공유하는 방식이 유일하다.

Markdown!

하지만, 글 작성할 때, Markdown 이라는 작성방식을 사용하는데, 이게 은근 매력이다.
정말 다양한 Format을 제공하지는 않지만, 내가 의도한 글을 작성하는데 하등 부족함이 없다.
그리고 특정 기능을 꺼내기 위해 마우스로 버튼을 이곳 저곳 누를 필요도 없이, 
직접 Text로 입력하면 기능이 활성화 되서 적용이 된다
게다가 Markdown으로 작성하면 자동적으로 실제 보여지는 화면으로 바로 바로 전환되고,
필요하면 바로 바로 Markdown 양식을 편집할 수 있다.

여튼... 이런 많은 장점이 있어, 메일을 보내기 전에 내 생각을 이곳에 적는데, 
문제는 여기에 적힌 글을 그대로 복사한 뒤, Outlook 텍스트에 붙이면
Markdown 양식으로 그대로 붙는다.

문제!  Outlook 으로 어떻게 보내나?

Obsidian에서는 Html 형식으로 깔끔하게 작성된 내용이 Markdown 형식으로 그대로 붙이니..
다시 편집해야 되나 싶었다.

 

HTML로

그래서 Outlook 내에 Markdown 지원여부 방법이나, 이 Markdown 내용을 변환할 무언가를 계속 찾았다.

그러다가, Obisidian의 커뮤니티 플러그인 중 "Copy doucment as HTML" 이라는 것을 찾았다.

이것을 깔아서 사용해보니,
문서 옵션에 Copy as HTML 명령이 생겼다.

이것을 통해 Markdown으로 만든 문서를 HTML로 끄집어 낼 수 있었다.

이 다음에 Outlook 으로 이 HTML을 밀어 넣는 방법인데... 없었다.!!!!!

 

그러다가, 바탕화면에 export.html 이라는 이름의 파일을 만든 뒤, 메모장을 이용해 앞서 Copy as HTML 한 내용을 그대로 붙여서 저장했다. 그리고 웹브라우저로 띄우니 왠걸 그럴싸하게 나온다.

이 내용을 그대로 긁어 Outlook 편집기에 붙이니 생각보다 잘 붙었다.

폰트 좀 조정하는 정도로 대략 모양도 그대로 옮겨진것 같았다.

(물론 이미지라든가, 특수 표현은 좀 이상하게 붙긴 했다.)

나중에 메모한 내용을 메일로 보낼때는 좀 편해질 것 같다.

 

정리

1. Obsidian 으로 작성한다.

2. Copy as HTML 로 HTML 코드를 클립보드에 담는다.

3. export.html 파일을 텍스트 편집기로 열고 클립보드의 HTML을 그대로 붙여 넣는다.

4. 웹브라우저를 이용해 export.html 을 띄운다.

5. 웹브라우저 상에 있는 화면을 모두 복사해서 Outllok 편집기에 붙여 넣는다.

 

단, 이것은 Outlook과 같이 HTML 편집기를 제공하지 않는 곳에서 발생되는 문제고, 대부분 HTML 소스를 직접 수정하기 위한 옵션을 제공한다면, HTML코드를 그대로 붙이는게 더 간단하고 빠르다!

728x90

사실 정확히 카카오 메일 계정 통합의 문제보다는, 2단계 인증 문제긴 하지만,
최소한 고객센터에서는 기존 다음 메일에서 쓴 암호가 아니라, 이번에 통합된 카카오 계정의 암호를 넣으라는 메시지는 있다.

문제는 고객센터의 글들을 확인할 수 없어(현재 2024-05-02 기준) 실제 내용은 잘 모르겠다.

일단 카카오 계정의 암호를 넣어보았는데, 계속 접속이 안되는 것이였다.
설정의 문제인지...Outlook이 최신 버전으로 바뀌면서 이상하게 아이디랑 암호를 넣는 창이 잘 안나오는데, 이 때문에 발생한 문제인지.. 도통 문제의 원인을 알 수 없었다.

그러다가, 2단계 인증이 설정되었을시에는 "앱 비밀번호"를 만들어서 그 비밀번호를 쓰라는 내용을 보게되었다.
(이 역시 고객센터 글이 읽혀지지 않아, google 검색으로 알게됨)

그래서 간신히 하나씩 찾아서 진행했다.

Kakao 계정 관리 접속

https://accounts.kakao.com/weblogin/account 으로 접속한다.

계정 보안

화면에 보이는 계정 보안에 들어간다.

2단계 인증

화면의 하단 쪽으로 내려보면 "2단계 인증"이라는 항목을 볼 수 있는데, 이 항목을 클릭해준다.

들어가려면, 다시 Kakao 계정 암호를 묻는다.

 

앱 비밀번호

2단계 인증 화면을 보면, 무슨 요약화면 같이 나오는데, 여기서 "앱 비밀번호" 항목 끝자락에 있는 ">"를 찾아 클릭한다. 처음에는 잘못봐서 없는 줄 알고 해맸다.

들어가면 아래와 같은 화면이 나오는데, "앱 비밀번호" 밑의 내용에다 적당한 이름을 넣는다. 나중에 어디에 발급했는지 알아보려면 조금은 잘 적어두는 편이 좋다. 그리고 생성 버튼을 누르면, 임시 비밀번호가 나온다.

이 비밀번호를 넣어주면 된다.

정리

예전 GMail 에서 제공했던 1회용 암호와 동일한 기능을 제공한다. 한번 발급된 뒤, 1회라도 사용되면 다른 곳에서는 저 암호를 쓸 수 없게 된다. 그래서 id/password 보다 훨씬 유용했는데, Gmail에서는 없어졌고, 여기에는 남은 것 같다.

여튼 2단계 인증을 시도하게 되면, 더 이상 ID/Password로는 로그인 처리가 불가능하므로, 반드시 이 앱 비밀번호라는 기능을 사용해야 한다.

이거 찾아 적용하느라, 1시간을 날렸다. -_-;;;

728x90

이 내용에 대해서 검색하려고 영어로 하는데... 약간의 애로사항이 있었다.
검색어는 이렇게 했다;.

regular expression parameter by quotes

그렇게 해서 찾은 글이 https://stackoverflow.com/questions/171480/regex-grabbing-values-between-quotation-marks 이였고, 이 글을 통해서 답은 얻었다.

정규 표현식은 아래와 같다.

\"(.*?)\"

즉 (.*?) 가 핵심이다.

위의 내용 처럼 Argument 값을 정규식에 대입하려면 Argument 전체 값이 필요한데, Main(string [] args)를 통해서 받은 args 값은 공백으로 전부 짤라놔서, 저 정규식을 대입해봐야 아무 도움이 안된다.
즉 자르기 전, 원본 Arguments 값을 얻어와야 한다.

string[] aryArgs = Environment.GetCommandLineArgs();            
string sArgOnly = Environment.CommandLine.Replace("\"" + aryArgs[0] + "\""  , "");

이제.. 저렇게 얻은 값을 " "  으로 꺼내려면 아래와 같이 코드를 짜면 추출할 수 있다.

Regex regex = new Regex("\"(?<arg>.*?)\"");

List<string> aryAllArgs = new List<string>();
MatchCollection matches = regex.Matches(sArgOnly);
foreach(Match match in matches)
{
    aryAllArgs.Add(match.Groups["arg"].Value);
}
728x90

개인적으로 메모장 보다는 이 notepad++을 자주 이용한다. 과거에는 UltraEdit와 같은 다양한 텍스트 편집 도구, 특히 유료 버전들을 많이 이용했었는데, 이 notepad++를 이용하고 난 이후에는 이것만 쓴다.

문제는 Windows 초기화(포멧)후 설정을 원래대로 복구하는데 매번 고생했다.

결론 부터 이야기하면 notepad++의 모든 설정 파일은 다음 위치에서 볼 수 있다.

%AppData%\Notepad++

윈도우 탐색기(Windows Explorer)의 경로창에 넣으면 바로 들어가진다.

해당 위치의 파일들을 모두 복사해가면 된다.

 

728x90

( 지금.... 2024/03/21 기준의 글로써, 이후 패치나 다른 고객지원등을 통해 변경될 수 있음)

인터넷 등기소에서 등기부등본을 출력하려고 사이트에 접속했다.
http://www.iros.go.kr/

 

대법원 인터넷등기소

 

www.iros.go.kr

일단 여기 접속하면 다양한 ActiveX나 관련 모듈들을 설치한다. 
애초에 Internet Explorer를 쓰라고 나오긴 하는데, Chrome이나 Firefox에도 되긴한다.
veraport-g3-x64 를 설치하면 대부분 관련된 대부분은 설치되긴 한다.

그런데, 이상하게 발급, 출력 부분에서 발급하려고 "결제", 상단에 나오는 팝업에서 "열기"를 하는 순간, 
RPRTRegisterXCtrl.exe 를 실행한다고 한다. 그래서 실행해! 라고 했는데.... 반응이 없다.
계속 기다려봤는데.. 역시 아무것도 동작하지 않는다.

처음에는 내 쪽에서 설정되거나 다른 프로그램과 오류가 있는줄 알았는데... 아니였다.

문제 원인

처음에는 단순 프로그램 충돌, 가상화시스템, 네트워크 ... 뭐 등등 다양한 부분에서 접근했다. 심지어 회사에서 놀고 있는 노트북이 있어서 거기다가도 했는데 동일했다. 단순 열람이나, 전자정부문서 지갑 전송 같은데서는 아무 문제가 없는데, 유독 이 "출력", "발급"에서는 터진다.

한 2시간 정도 삽질하다가.. Event Viewer를 보는데... 메시지가...

"C:\Program Files (x86)\markany\maepscourt\rprtregisterxctrl.xgd"에 대한 활성화 컨텍스트를 생성하지 못했습니다. 
종속 어셈블리 Microsoft.VC90.MFC,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8"을(를) 찾을 수 없습니다. 
자세한 진단을 위해서는 sxstrace.exe를 사용하십시오.

....

뒷골이 싸했다.

패키징 실패. 이 프린터용 프로그램인 RPRTRegisterXCtrl.exe 패키징할 때, 이에 연관된 라이브러리를 같이 설치하지 않은 것이다. 만일 사용자가 오랫동안 포멧하지 않고 사용하면서 다양한 프로그램을 깔았다면, 분명 설치되어 있을 라이브러리 겠지만, 나 같이 깔끔하게 포멧을 하고 새로 설치해서 사용하는 사람의 경우 저 라이브러리가 없을 가능성이 높은데... 이거 패키징 한 친구는 지 컴퓨터에서 잘 된다고 넘어간듯...

해결 방법

https://learn.microsoft.com/ko-kr/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version

 

지원되는 최신 Visual C++ 재배포 가능 패키지 다운로드

이 문서에는 최신 버전의 Visual C++ 재배포 가능 패키지에 대한 다운로드 링크가 나열되어 있습니다.

learn.microsoft.com

사이트에서 Visual Studio 2008(VC++ 9.0) SP1(더 이상 지원되지 않음) 부분에 있는 x86의 9.0.30729.5677 버전을 설치해야 한다. 파일이름은 vcredist_x86.exe   (직접 다운로드 경로는 아래와 같다.)

https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe

저걸 설치하면 된다.

 

결론

일차적으로는 패키징을 잘못한게 하나.

이차적으로는 대체 보안/패치도 지원하지 않는 저 오래된 라이브러리를 아직도 쓴다는게 하나.

삼차적으로는 저 따위 보안 솔루션을 쓰는 것 자체지 않을까? 차라리 보안 PDF 파일을 보내주는게 더 나을듯.

 

728x90

기존에 Yona 를 구축해서 버전관리를 잘해오고 있는데, 문제는 알림 메일이였다.
지금까지 계속 google의 SMTP로 잘 운영해오다가, 어느 순간 google의 로그인 방식이 보안 정책에 따라, OAuth 방식이 아니면 더 이상 예전 처럼 아이디/패스워드 기반의 로그인을 지원하지 않는 것이다.
그래서 naver.com 내에 계정을 하나 파서 그 안에 있는 POP3/IMAP 기능을 활성화 했고, 거기서 제공하는 SMTP 설정 값을 이용해 Yona의 application.conf 값을 아래와 같이 수정했다.

smtp.startssl = true
smtp.host = smtp.naver.com
smtp.port = 587
smtp.auth = true
#smtp.ssl = true
smtp.password = "xxxxxxx"
smtp.domain = naver.com
smtp.user = "xxxxxxx@naver.com"

설정을 변경한 뒤 Yona를 다시 시작했는데.. 왠걸.. 아래와 같은 에러가 떨어진다.

2024-03-06 13:26:51,466 - [WARN] - from application in play-akka.actor.default-dispatcher-974 
Failed to send a notification: org.apache.commons.mail.HtmlEmail@1720365d
org.apache.commons.mail.EmailException: Sending the email to the following server failed : smtp.naver.com:465
	at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1410)
	at org.apache.commons.mail.Email.send(Email.java:1437)
	at info.schleichardt.play2.mailplugin.MailPlugin$$anonfun$6.apply(MailPlugin.scala:60)
	at info.schleichardt.play2.mailplugin.MailPlugin$$anonfun$6.apply(MailPlugin.scala:54)
	at info.schleichardt.play2.mailplugin.MailPlugin.send(MailPlugin.scala:68)
	at info.schleichardt.play2.mailplugin.api.Mailer$.send(Mailer.scala:8)
	at info.schleichardt.play2.mailplugin.Mailer.send(Mailer.java:15)
	at controllers.ProjectApp.sendTransferRequestMail(ProjectApp.java:775)
	at controllers.ProjectApp.transferProject(ProjectApp.java:634)
	at Routes$$anonfun$routes$1$$anonfun$applyOrElse$191$$anonfun$apply$191.apply(routes_routing.scala:3708)
	at Routes$$anonfun$routes$1$$anonfun$applyOrElse$191$$anonfun$apply$191.apply(routes_routing.scala:3708)
	at play.core.Router$HandlerInvokerFactory$$anon$4.resultCall(Router.scala:264)
	at play.core.Router$HandlerInvokerFactory$JavaActionInvokerFactory$$anon$15$$anon$1.invocation(Router.scala:255)
	at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:55)
	at Global$2.call(Global.java:274)
	at actions.AnonymousCheckAction.call(AnonymousCheckAction.java:57)
	at actions.IsAllowedAction.call(IsAllowedAction.java:68)
	at actions.AbstractProjectCheckAction.call(AbstractProjectCheckAction.java:93)
	at play.db.ebean.TransactionalAction$1.call(TransactionalAction.java:21)
	at play.db.ebean.TransactionalAction$1.call(TransactionalAction.java:18)
	at com.avaje.ebeaninternal.server.core.DefaultServer.execute(DefaultServer.java:715)
	at com.avaje.ebeaninternal.server.core.DefaultServer.execute(DefaultServer.java:709)
	at com.avaje.ebean.Ebean.execute(Ebean.java:1264)
	at play.db.ebean.TransactionalAction.call(TransactionalAction.java:18)
	at play.core.j.JavaAction$$anonfun$11.apply(JavaAction.scala:82)
	at play.core.j.JavaAction$$anonfun$11.apply(JavaAction.scala:82)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
	at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:40)
	at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:46)
	at play.core.j.HttpExecutionContext.execute(HttpExecutionContext.scala:32)
	at scala.concurrent.impl.Future$.apply(Future.scala:31)
	at scala.concurrent.Future$.apply(Future.scala:485)
	at play.core.j.JavaAction$class.apply(JavaAction.scala:82)
	at play.core.Router$HandlerInvokerFactory$JavaActionInvokerFactory$$anon$15$$anon$1.apply(Router.scala:252)
	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:130)
	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:130)
	at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:129)
	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:128)
	at scala.Option.map(Option.scala:145)
	at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:128)
	at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:121)
	at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:483)
	at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:483)
	at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:519)
	at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:519)
	at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$14.apply(Iteratee.scala:496)
	at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$14.apply(Iteratee.scala:496)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
	at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
	at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
	at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
	at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
	at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
	at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: javax.mail.MessagingException: Could not connect to SMTP host: smtp.naver.com, port: 465;
  nested exception is:
	javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
	at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1972)
	at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:642)
	at javax.mail.Service.connect(Service.java:317)
	at javax.mail.Service.connect(Service.java:176)
	at javax.mail.Service.connect(Service.java:125)
	at javax.mail.Transport.send0(Transport.java:194)
	at javax.mail.Transport.send(Transport.java:124)
	at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1400)
	... 56 more
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
	at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
	at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:103)
	at sun.security.ssl.TransportContext.kickstart(TransportContext.java:227)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:433)
	at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:548)
	at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:352)
	at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:207)
	at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1938)
	... 63 more

그런데 에러를 찬찬히 살펴보니 아래와 같은 문장이 눈에 딱 띄었다.

Caused by: javax.mail.MessagingException: Could not connect to SMTP host: smtp.naver.com, port: 465;
  nested exception is:
	javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
	at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1972)
	at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:642)

이상해서, 과거 Yona의 Issue 창을 뒤져보니, 답글 중에 아래와 같은 답변을 발견했다.

https://github.com/yona-projects/yona/issues/746

 

이메일 발송관련 · Issue #746 · yona-projects/yona

안녕하세요, 프로젝트 이관 중에 확인 메일이 안와서 이상하다 싶어서 확인하니까, 현재 메일에서 계속 오류가 발생합니다. 먼저 제쪽 환경은 아래와 같습니다. [OS] Ubuntu - 16.04.7 LTS (Xenial Xerus) [J

github.com

저 내용에서 중요한 건 Stackoverflow 링크 안의 답글인데, 답글 중에,

JRE_HOME/lib/security/java.security:

파일 안에 있는

jdk.tls.disabledAlgorithms

값을 수정하면 된다는 것이다.

해결 방법

일단, 지금 운영 중인 서버의 Java 파일 중에 java.security를 찾는다.
리눅스를 기준으로 이야기하면 다음과 같이 넣으면 찾을 수 있다.

find | grep java.security

root 권한이 있어야 수정되므로 sudo 로 해당 파일을 열어준다.

그리고 jdk.tls 를 검색하면 아래와 같은 내용을 볼 수 있다.

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves

저 항목 중에 SSLv3, TLSv1, TLSv1.1 을 삭제하고 저장하도록 한다.

그러면 해결된다.

728x90

다른 곳에서 전체 백업된 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

+ Recent posts

728x90