최근 포토로그


zebra에 한글폰트 넣기 C#

먼저 2가지 방법이 있다.

1번은 USB를 통하여 출력할때, 쓰는 방법이고
2번은, serial을 통하여 출력할때, 쓰는 방법이다.

1번은 버퍼를 통하여 인쇄를 하며, 출력시 프린터대기창이 뜬다.


이 방법으로 파일을 전송하면 된다.

2번째 방법은 시리얼 포트로 전송하는 것이므로 시간이 많이 걸린다. (대략 20분)
첨부된 파일의 ZEBRA_TO_FONT.bat 를 실행하면 한글 출력을 할수 있는데 (COM7 을 자신의 프린터와 연결된 포트로 바꾼다. ETC: COM1
) COM 포트 번호만 바꾸고 실행하면 된다.



대충 다음과 같은 모습을 거의 20분 가까이 소모할 것이다.










NSIS로 설치파일 만들기 C#

NSIS 다운로드 및 설치



스크립트 편집기 다운로드 및 설치
http://hmne.sourceforge.net/

마법사 실행하기





요즘쓰는 SSMS 애드온 MSSQL과 ORACLE

ApexSQL 이라는 애드온이다.


이게 SQL search 랑 달리 문장내에 한칸 띄워져 있어도 검색이 된다.

단, 단점은 색표시가 안된다.

어느 부분에 이 글자가 있는지, 찾을려고 하면 눈이 고생해야 함.


근데 그것 빼고는 아름다움.

SQL 포멧팅은 상용과 비교될 정도로 아름다운 결과물을 만들어내지만, 셋팅이 복잡하다. (그만큼 다양하다.)

암튼 맘에드는 MSSQL 내용찾는 거라서 추천함.


잘 써서 sp_helptext 를 탈출해보자.






홍미노트8 Pro 직구폰 통화안될때 제야의 종



샤오미 전화앱에서 버튼을 간단하게 아래 번호를 입력하고

*#*#86583#*#*

2~3번 재부팅하면 유심이 활성화 된다.!!!



MSSQL 단순 MERGE INTO

    MERGE INTO MWIPEXTRES AUT
    USING (SELECT 'X' AS DUAL) DUAL
       ON ( AUT.RES_NO  = @IN_RES_NO
          )
    WHEN MATCHED THEN
              UPDATE SET UPTUSER = @IN_UPD_ID
                             ,UPTDATE = GETDATE()
    WHEN NOT MATCHED THEN
          INSERT ( RES_NO
                  ,KIT_LOT_NO
                  ,SEQ
           )
          VALUES ( @IN_RES_NO
                  ,@IN_KIT_LOT_NO
                  ,1
                  ); 

뭐 이런식으로 쓰면 된다.
이건 조인을 사용하지 않는 문장이고, 조인을 사용한다면 
SELECT 'X' AS DUAL 
구문을 SELECT TABLE문으로 바꾸면 된다.

카톡 PC버전 너무 짱나네 이거

몇달전부터 카톡 PC버전에서 이미지가 잘 수신이 안된다.

다 안되면 그런가보다 하는데, 몇개는 오고 몇개는 안온다.

이런게 진짜 미치는 거지



해결방법이 없나?


MERGE INTO 를 극복해보자 MSSQL과 ORACLE

내가 구세대라서 그런지 쿼리를 좀 보수적으로 하는 경향이 있다.

즉, 
MERGE INTO 나 CTE같은 거 잘 안쓰려고 하더라구, 근데 어쩔수 없이 써야 하는 경우에는 쓰는데
자꾸 문법이 헷갈린다. 그래서 써본다. MERGE INTO 문법

MSSQL 의 경우



        MERGE INTO 엄청난테이블 MST
        USING (SELECT 'X' AS DUAL) DUAL
           ON (     PLANT_CD    = @IN_PLANT_CD
                AND FACT_CD     = @IN_FACT_CD
                AND WORD_NO     = @IN_WORD_NO
                AND INSP_CYCLE  = @IN_INSP_CYCLE
              )
         WHEN MATCHED THEN
              UPDATE SET OK_DECISION = @V_OK_DECISION
                        ,INSP_DATE   = GETDATE()
                        ,INSP_DAY    = @V_DT 
                        ,INSP_TM     = @V_TM
                        ,INSP_ID     = @IN_CHECK_ID 
                        ,UPTDATE     = GETDATE()
                        ,UPTUSER     = @IN_USER_ID
         WHEN NOT MATCHED THEN
              INSERT ( PLANT_CD
                      ,FACT_CD
                      ,INSITEM_CD
                      ,REVISION
                      ,INSP_CYCLE
                      ,WORD_NO
                      ,MAT_CD
                      ,OK_DECISION
                      ,INSP_DATE
                      ,INSP_DAY
                      ,INSP_TM
                      ,INSP_ID
                      ,CRTDATE
                      ,CRTUSER
                       )
              VALUES ( @IN_PLANT_CD
                      ,@IN_FACT_CD
                      ,@IN_INSITEM_CD
                      ,@IN_REVISION
                      ,@IN_INSP_CYCLE
                      ,@IN_WORD_NO
                      ,@IN_MAT_CD
                      ,@V_OK_DECISION
                      ,GETDATE()
                      ,@V_DT
                      ,@V_TM
                      ,@IN_CHECK_ID 
                      ,GETDATE()
                      ,@IN_USER_ID
                      ); 


이 경우는 테이블 조인이나 그런거 필요없이 특정한 칼럼의 값을 위하서 쓰는 문법임.

    MERGE INTO 엄청중요한테이블 AUT
    USING ( SELECT ROLE_CD
              FROM 조인하는테이블
             WHERE DEPT_CD = @IN_DEPT_CD
   AND USE_YN = 'Y'
          ) TMP
       ON ( AUT.USER_ID = @IN_USER_ID AND
            AUT.ROLE_CD = TMP.ROLE_CD
          )
     WHEN NOT MATCHED THEN
          INSERT ( USER_ID          -- 사용자 ID 
                  ,ROLE_CD          -- 권한 코드
                  ,CRTUSER          -- 등록자 ID
                  ,CRTDATE          -- 등록일시
                   )
          VALUES ( @IN_USER_ID
                  ,TMP.ROLE_CD  
                  ,@IN_UPD_ID
                  ,GETDATE()
                  ); 


MSSQL 애드온 (SP_HELPTEXT의 대안) - sp 내용보기 MSSQL과 ORACLE

여기 글 보신분은 알겠지만 내가 꾸준히도 sp_helptext에 대해 썼다.

그만큼 더러운데 아직까지 안고쳐져서 포기하는 프로시저라는 말이죠.

엔터키 자동입력 문제, 텝정렬 무시 문제... 등등


그래서 그걸 한방에 해결해줄 해결사를 찾았는데, 그건 바로

"SQL Search" 라는 애드온이다.


링크는 아래


이걸 누르면 다운로드 할 수 있다.


그리고 쓰는 방법은 간단하다.

깔면 MSSM에 장착된다.


요로코롬 장착되는데 이걸 가지고 

버튼 누르면 


요렇게 DB를 선택할 수 있고

매칭은
text만 검색할지, 아니면 이름으로 검색할지, 칼럼으로 검색할지가 나온다. SP 내용 검색하는 기능으로 최고다


이걸로는  프로시저, 함수, 뷰 등을 검색할 수 있다.

"Match Whole Word Only" 체크하면 문장으로 검색할 수 있다.

즉, "insert into aaa_tbl" 로 검색하면 
이렇게 검색되는 것이

체크를 하면

글자가 다 있는거만 나온다.

그리고 더블클릭하면 프로시저에 간다.


최고임.

USIM에 대한 고찰 제야의 종

내가 해외에 가면 USIM칩 사서 꼽고 통화하는데, 암만 오래걸려도 30분이면 처리가 된다.

근데, 한국은 꼭 단말기를 껐다가 켜야 하고, 기둘려야 하고 이런다.

유심을 왜 이렇게 어렵게 만들어놨는지 모르겠다.
인증절차가 그리 어렵나???

암튼 계속 껐다가 켜야하는 이유를 잘 모르겠다.


그냥 하루동안 통화 안되어서 짜증나서 그랬다.

openxcom(OXCE) 를 다시 시작했다.

최근 오리지날 xcom[TFTD)에 확장모드가 있다는 걸 알았다.

TWOTS 라는 건데, 이거 어렵고 오래걸린다.


혹시나해서 superhuman 으로 플레이 했는데, 씨붕 암만 쏴도 안죽는 놈들도 있어서 도저히 superhuman 은 저장질 없이 하는 건 스트레스 만빵이라서 못하겠다.

중간정도 어려움으로 하면 스트레스 없이(?) 할 수 있을 거 같다.

그래도 더럽게 시간 많이 걸린다.

screen003.png


screen003.1.png

인도 AirTell 통신비 미분류

유심빼고 통신비만 보면 하루 1.5기가에 200루피다 28일 쓸수 있는 것이고...

이거 우리돈으로 환산하면 약, 3360원 정도네....

씨불 디게 싸네.

한국 저렴한 통신사 알아보면 이거 제3통신사를 써도 2배이상이다.

그러고보면 한국 통신비 싸다는 말 개구라임.

인도라서 그렇다고?

그럼 할 말 없지머.





MSSQL 임시테이블 활용하기 MSSQL과 ORACLE

물론 테이블변수가 작게 쓸려고 하거나 컴파일 하지 않으려고 하면 쓰임새가 많다.

하지만, 
임시테이블 (#)이 붙은 테이블은 쓰기에 따라서 아름다운 결과물을 만들어 낼수 있다.

MSSQL 임시테이블은 #을 하나만 쓴다면 자기영역 내에서는 어디에서든 쓸수 있다.

즉, 내부 프로시저 안과 내가 호출하는 프로시저내에서는 자유롭게 부를 수 있다는 거다.

즉,

아래 셈플을 보자

=============================================================

-- DROP PROC dbo.usp_TableVar
go
CREATE PROC dbo.usp_TableVar

AS

create table #Tb_test 
(

OrderID int identity(1,1) PRIMARY KEY NONCLUSTERED
, OrderDate datetime CHECK (OrderDate >= '1900-01-01')

)

INSERT INTO #Tb_test values ('20180101')
INSERT INTO #Tb_test values ('19910101')

--SELECT TOP 10 OrderDate FROM Orders --OrderID 컬럼은 지정할 필요 없다.


UPDATE #Tb_test SET OrderDate = OrderDate + 1

DELETE #Tb_test WHERE OrderDate > '1996-07-10'

exec usp_TableVar2

SELECT * FROM #Tb_test

GO



-- DROP PROC dbo.usp_TableVar2
go
CREATE PROC dbo.usp_TableVar2

AS


INSERT INTO #Tb_test values ('20180102')
INSERT INTO #Tb_test values ('19910103')
exec usp_TableVar3


GO

-- DROP PROC dbo.usp_TableVar3
go
CREATE PROC dbo.usp_TableVar3

AS


INSERT INTO #Tb_test values ('20180105')
INSERT INTO #Tb_test values ('19910106')

GO

EXEC dbo.usp_TableVar


-- DROP PROC dbo.usp_TableVar
-- DROP PROC dbo.usp_TableVar2
-- DROP PROC dbo.usp_TableVar3

============================

usp_TableVar 프로시저가 usp_TableVar2를 부르고 usp_TableVa3을 부른다.

그럼에도 임시테이블 
#Tb_test 에는 접근 가능하고, 다 추가/수정/삭제 되다.


쿼리결과에 TAB, LF 등이 표결과에서 안 나올때 MSSQL과 ORACLE

참 간단한 거였는데 이제 알았다.



첫번째꺼에 보면 표로 결과를 보내면 텝키나 라인조정이 이상하게 되어서 결과가 space한개로 바뀌어서
나중에 복사하면 결과물이 이상하게 된다.


즉 

이런 식으로 텝이 있으면 이걸 복사하는 과정에서 mssql은 텝무시가 디폴트로 되어있어서 결국 

이런 방식으로 텝이 없어지면서 거기에 스페이스가 알아서 먹히면서 줄 정렬이 지독하게 이상하게 되는 것이다.

이거를 막기 위해서는 이전에는 짜증나게도 "텍스트 결과로 표시"를 사용했다.

즉,
이렇게 하면 출력이 잘되었지만, 
나는 항상 표로 결과물을 도출하는데, SP 내의 결과를 보기위해서 자꾸 왔다갔다 해야 하는 것 때문에 짜증 지수가 MAX였다.



그런데 오늘 SSMS 설정 좀 건드리다가 알아낸 사실

"복사 또는 저장 시 CR/LF 보존"
이라는 게 결국 그걸 잘 해주는 거였네.

이렇게 하고 새탭 열어서 이래저래 테스트 해보니
표결과는 이상하게 보여도, 복사&붙여넣기를 하면 TAB키도 잘 표시되고 이쁘게 나온다.

이런거 정말 필요했는데 아직도 못했던 내가 미워





MSSQL 의 SSMS 에서 암호저장이 안될 때,

보안 문제는 있지만 저장 안되는 버그가 나를 괴롭힌다.

그래서 구글링해보니


C:\Users\사용자\AppData\Roaming\Microsoft\Microsoft SQL Server\140\Tools\Shell
밑의 파일을 삭제하고 다시  ssms 껏다가 켜라고 되어있더라.

해보니 잘된다.


단, 이전 저장한 로그들 싹다 날라간다.


저 위의 
140은 내가 14버전을 쓰고 있어서 그렇다.

버전별로 안에 들어가 있는 파일이 조금 다르더라.

암튼 그쪽 파일 지우면 만사 OK


심심해서 써보는 오픈엑스컴 TFTD - 슈퍼휴먼 난이도. 게임?

예전에 엑스컴 TFTD 를 슈퍼휴먼 난이도로 클리어한 기억이 있다.

근데 생각해보면 이전 엑스컴의 TFTD는 슈퍼휴먼 난이도라고 해도, 세이브모드가 있었기 때문에 내가 클리어를 쉽게(?) 했던 기억이 있다.

그런에 오픈엑스컴(OpenXcom)는 아이언모드가 있다.

한마디로 저장질(?)을 못하는 버전이다.

근데 이 아이언모드로 하면 빡지는 부분이 밤에 공격하면 시야가 극도로 좁아지는 단점 때문에
낮에 접근하려고 기다려야 하는데, 항구미션, 배미션은 시간지나면 사라지기 때문에 대중 짐작해서 출발해야 한다.

그렇다고 웨이포인트에 기다려도 잘 사라지기 때문에 시간이 빡빡할 경우 그냥 감으로 출동해버리는 수가 많다.
그러다보면 어두운데서 조명탄 던지면서 해야 한다.

예전 처음했던 슈퍼휴먼의 난이도는 고폭탄을 때려도 섹토이드가 죽지 않는 경우도 있었다. - 아니 좀 있었다. - 
그리고 이놈들 흥분하면 심심하면 외계수류탄을 까서 작살나는 경우가 너무 많았다.

다행히(?) 오픈엑스컴에서는 수류탄은 잘 안쓰는데, 갑자기 디스트럽터 펄스 런처를 잘(?) 발사해서 몰살 당하는 경우가 잦더라.

거기다가 오픈엑스컴에서는 초반 2~3월에도 외계인들이 갑자기 기지로 처들어오는 경우가 생겼다.
아예 소닉수류탄 정도만 개발했는데 외계인이 처들어오면 그게 상대가 되냐?

거기다가 5개월 넘어가면 소닉캐논도 개발 안되었는데, 랍스터가 처들어 와서 도저히 답이 없는 경우도 생겼다.


허.... 어쨌거나 오픈엑스컴 TFTD 2018년 9월버전은 수퍼휴면 아이언모드로 할려니 진짜 박시게 해야 한다는 걸 깨달았다.

몇번 당하다가 
지금 3월까지 진행했는데 이거 성공할 것 같다.

나중에 유투브 방송을 할수 있다면 이거 라이브로 방영하는 것도 좋은 거 같다. 
ㅎㅎㅎ


SP_HELPTEXT의 고질적인 문제에 대한 고찰 MSSQL과 ORACLE

내가 여기에 SP_HELPTEXT 에 대한 글만 여러 개 썼었는데, 항상 문제가 발생하였다.

왜 이런 귀찮은 일을 하는지 물어본다면 추가 라인이 갑자기 생기는 문제 때문이다.

내 작업의 특성상 MSSQL 스토어드프로시저를 많이 쓰는데, 
SSMS를 사용하여 프로시저 수정 을 클릭했을 때랑, SP_HELPTEXT를 사용하여 프로시저를 불렀을때랑 결과물이 다르게 나타나는 문제 때문이다.


이게 한번만 수정하면 상관없는데, 여러번 수정을 거치면 기하급수적으로 이쁘게 만들었던 라인들이 엉망이 되어간다는 점이다.

물론 다른 툴을 사용하면 되겠지만 나는 MSSQL 순정, 거기에 SSMS를 사용하므로 SP_HELPTEXT를 수정하지 않으면
결국 에러를 발생시키거나 아니면 엄청나게 이상한 라인을 참으며 작업을 해야 한다.

그 결과의 셈플 화면이 이건데

위에처럼 "WHERE" 부분이 갑자기 튀어나와서 라인이 엉클러지는 문제이다.


그래서 수정을 거치게 되었는데 그게 SP_HELPTEXT2 인데,
문제는 내가 CREATE PROCEDURE 라는 글자를 매번 ALTER PROCEDURE 라는 글자로 바꾸기 싫다는 거다.

그레서 결과물을 커서로 돌려서 첫째라인을 바꾼 후에 PRINT를 출력하였더니
빈칸에 공백이 한개씩 찍혀나오는 버그를 발겼했다.
씨붕
아래 화면에 적나라하게 나타난다.
스페이스가 한칸씩 있다는 말이지. 또한 PRINT의 특성상 맨 마지막 라인 이후에 엔터키가 하나가 먹힌다.
이쯤되면 짜증이 좀 난다.

그래서 어쩔 수 없이 PRINT 부분을 다시 테이블에 넣고 표형태로 결과물을 찍어야 내가 원하는 결과물을 얻어낼 수 있다는 것을 발견했다.


아름다운 결과물을 먼저 감상하자.
이 화면에서는 잘 안보이지만, 빈라인에 공백 1개씩 추가되는 것도 없고, CREATE PROC를 ALTER PROC로 바꾸어주고
그리고 맨 마지막 라인도 깔끔하게 끝나는 버전으로 완성했다.


기뻐서 이것을 최종버전으로 배포합니다.

쌩유

아래부분은 프로시저입니다. ==================================>
ALTER PROCEDURE SP_HELPTEXT2 (@ProcName NVARCHAR(256))
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @SEQ INT
    DECLARE @TEXT NVARCHAR(4000)

    DECLARE @PROC_TABLE TABLE (X1  NVARCHAR(MAX))


    DECLARE @Proc NVARCHAR(MAX)
    DECLARE @Procedure NVARCHAR(MAX)
    DECLARE @ProcLines TABLE (PLID INT IDENTITY(1,1), Line NVARCHAR(MAX))

    DECLARE @NEW_ProcLines TABLE (PLID INT IDENTITY(1,1), Line NVARCHAR(MAX))

    SELECT @Procedure = 'SELECT DEFINITION FROM ['+db_name()+'].SYS.SQL_MODULES WHERE OBJECT_ID = OBJECT_ID('''+@ProcName+''')'

    insert into @PROC_TABLE (X1)
          exec  (@Procedure)

    SELECT @Proc=X1 from @PROC_TABLE

    WHILE CHARINDEX(CHAR(13)+CHAR(10),@Proc) > 0
    BEGIN
          INSERT @ProcLines
          SELECT LEFT(@Proc,CHARINDEX(CHAR(13)+CHAR(10),@Proc)-1)
          SELECT @Proc = SUBSTRING(@Proc,CHARINDEX(CHAR(13)+CHAR(10),@Proc)+2,LEN(@Proc))
    END
    --* inserts last line
    INSERT @ProcLines
    SELECT @Proc ;

    --SELECT Line FROM @ProcLines ORDER BY PLID


    DECLARE SCRIPTCURSOR9 CURSOR LOCAL FORWARD_ONLY STATIC FOR
        SELECT PLID, Line FROM @ProcLines ORDER BY PLID

    OPEN SCRIPTCURSOR9

    FETCH NEXT FROM SCRIPTCURSOR9 INTO @SEQ, @TEXT

    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF @SEQ <= 1
        BEGIN
            SET @TEXT = REPLACE(@TEXT, 'CREATE PROC', 'ALTER PROC')
            SET @TEXT = REPLACE(@TEXT, 'CREATE FUNC', 'ALTER FUNC')
            SET @TEXT = REPLACE(@TEXT, 'CREATE VIEW', 'ALTER VIEW')
        END
        insert into @NEW_ProcLines 
               SELECT @TEXT
        --PRINT @TEXT

        FETCH NEXT FROM SCRIPTCURSOR9 INTO @SEQ, @TEXT
    END

    CLOSE SCRIPTCURSOR9
    DEALLOCATE SCRIPTCURSOR9

    SELECT Line FROM @NEW_ProcLines ORDER BY PLID

    --DROP TABLE  @ProcLines

END
========================================================

맘 놓고 쓰시라



귀찮아서 쓰는 MSSQL 테이블, SP, 칼럼, 뷰 관련 목록 정보 조회 MSSQL과 ORACLE

--테이블 목록 가져오기:
SELECT * FROM sysobjects WHERE xtype='U'

--뷰:
SELECT * FROM sysobjects WHERE xtype='V'

--프로시져:
SELECT * FROM sysobjects WHERE xtype='P'


--테이블 리스트
SELECT * FROM  INFORMATION_SCHEMA.TABLES
--뷰 리스트
SELECT * FROM  INFORMATION_SCHEMA.VIEWS
--컬럼 리스트
SELECT * FROM  INFORMATION_SCHEMA.COLUMNS
--컬럼 키값
SELECT * FROM  INFORMATION_SCHEMA.KEY_COLUMN_USAGE

--프로시져
SELECT * FROM INFORMATION_SCHEMA.ROUTINES
--프로시져 파라메타값
SELECT * FROM  INFORMATION_SCHEMA.PARAMETERS

 

--컬럼 정보 가져오기
SELECT
 A.TABLE_CATALOG
 ,A.TABLE_NAME
 ,A.ORDINAL_POSITION
 ,A.COLUMN_NAME
 ,A.DATA_TYPE
 ,ISNULL(A.CHARACTER_MAXIMUM_LENGTH,'')
 ,ISNULL(A.NUMERIC_PRECISION,'')
 ,A.IS_NULLABLE
 ,ISNULL(A.COLUMN_DEFAULT,'')
 ,ISNULL(B.CONSTRAINT_NAME,'')
 ,ISNULL(A.CHARACTER_SET_NAME,'')
 ,ISNULL(A.COLLATION_NAME,'')
 ,CASE WHEN ISNULL(C.NAME,'') = '' THEN '' ELSE 'Identity' END auto
FROM 
 INFORMATION_SCHEMA.COLUMNS A
 LEFT OUTER JOIN
 INFORMATION_SCHEMA.KEY_COLUMN_USAGE B
 ON A.TABLE_NAME = B.TABLE_NAME 
 AND A.COLUMN_NAME = B.COLUMN_NAME
 LEFT OUTER JOIN
 syscolumns C 
 ON C.ID = object_id(A.TABLE_NAME) AND A.COLUMN_NAME = C.NAME AND C.COLSTAT & 1 = 1 
WHERE
 A.TABLE_NAME = '테이블명'
ORDER BY A.ORDINAL_POSITION


SP_HELPTEXT 의 완성판( 줄이 밀리는 현상 해결) MSSQL과 ORACLE

SP_HELPTEXT 를 쓰다보면 자꾸 라인이 깨지는 현상이 가끔 가다가 발견한다.

이게 현상의 원인이 무엇인지 알아내지 못해서 몇년동안 고생해서 
차라리 SSMS에서 그냥 수정을 누르거나 라인을 일일이 다시 조정해주고 실행해주는 번거로움을 겪어야 했다.

이거 SP 많이 다루는 사람은 알겠지만, 정말 큰 스트레스다.

그래서 구글링은 몇년동안 지속적으로 한 결과 결국 답을 찾아냈다.


찬양하라 구글신이여!!!!


이제 드디어 SP_HELPTXTX의 버그 없는 판을 만든 것이다.

SP 참조 (참고로 여기 버전은 ALTER PROC부분으로 수정한다든지, 콘솔창에 찍어주는 부분도 포함되었다.
뜯어보시고 수정하시라.


==================================================
CREATE PROCEDURE SP_HELPTEXT2
( @PROCNAME NVARCHAR(256)
)
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @PROC_TABLE TABLE (X1  NVARCHAR(MAX))

    DECLARE @PROC NVARCHAR(MAX)
    DECLARE @PROCEDURE NVARCHAR(MAX)
    DECLARE @PROCLINES TABLE (PLID INT IDENTITY(1,1), LINE NVARCHAR(MAX))
    DECLARE @SEQ INT
    DECLARE @TEXT NVARCHAR(4000)

    SELECT @PROCEDURE = 'SELECT DEFINITION FROM ['+DB_NAME()+'].SYS.SQL_MODULES WHERE OBJECT_ID = OBJECT_ID('''+@PROCNAME+''')'

    INSERT INTO @PROC_TABLE (X1)
          EXEC  (@PROCEDURE)

    SELECT @PROC=X1 FROM @PROC_TABLE

    WHILE CHARINDEX(CHAR(13)+CHAR(10),@PROC) > 0
    BEGIN
          INSERT @PROCLINES
          SELECT LEFT(@PROC,CHARINDEX(CHAR(13)+CHAR(10),@PROC)-1)
          SELECT @PROC = SUBSTRING(@PROC,CHARINDEX(CHAR(13)+CHAR(10),@PROC)+2,LEN(@PROC))
    END
    --* INSERTS LAST LINE
    INSERT @PROCLINES
    SELECT @PROC ;
    -- 이부분을 넣으면 테이블그리드로 나온다.
    --SELECT LINE FROM @PROCLINES ORDER BY PLID


    DECLARE SCRIPTCURSOR9 CURSOR LOCAL FORWARD_ONLY STATIC FOR
        SELECT PLID, LINE FROM @PROCLINES ORDER BY PLID

    OPEN SCRIPTCURSOR9

    FETCH NEXT FROM SCRIPTCURSOR9 INTO @SEQ, @TEXT

    WHILE @@FETCH_STATUS = 0
    BEGIN
        -- 1번라인에 CREATE 부분을 수정
        IF @SEQ <= 1
        BEGIN
            SET @TEXT = REPLACE(@TEXT, 'CREATE PROC', 'ALTER PROC')
            SET @TEXT = REPLACE(@TEXT, 'CREATE FUNC', 'ALTER FUNC')
            SET @TEXT = REPLACE(@TEXT, 'CREATE VIEW', 'ALTER VIEW')
        END
        PRINT @TEXT

        FETCH NEXT FROM SCRIPTCURSOR9 INTO @SEQ, @TEXT
    END

    CLOSE SCRIPTCURSOR9
    DEALLOCATE SCRIPTCURSOR9

    --DROP TABLE  @PROCLINES

END

SSMS(SQL Server Management Studio) 단축키 변경하기 MSSQL과 ORACLE

MSSQL 의 쿼리서버관리스튜디오는 - 왜 이리 적당한 한글명칭이 없는거야? -
단축키 변경이 좀 특이하다.

예전에 주석처리하기 단축키가 Ctrl+Shift+C, CTRL+Shift+R
이었는데, 이제는 너무 달라져서 두번, 세번 키를 타이핑해야 해서 내가 짜증나서 

Ctrl+Shift+>
Ctrl+Shift+<

로 바꾸기로 했다.

근데 이게 좀 복잡하니 자세히 써본다.

먼저 옵션->환경->키보드로 가면 
편집.선택영역을주석으로처리 가 보인다.


제거를 두번 누르기

그러면 바로가기 키 누리기에서 단축키 넣고 할당 버튼



간만에 xcom2(TFTD)를 superhuan, ironman 으로 했다. 게임?

간만에 했는데, ironman 이라서 save Load 짓거리를 못하니깐, 조심스럽게 하게 되더라

초반에 Deep one Terror 놈을 못잡아서 고생했는데,
lobster man 나왔으니 10분의 1 정도는 깬거 같다.

근데 이정도 되면 귀찮을 뿐.

mssql에서 table 스크립트 뽑아내기 MSSQL과 ORACLE

하다보면 알겠지만, create table 스크립트 뽑아내는게 정말 귀찮다.
그래서 구글링을 했다.

나는 dbo나 이런거 붙는 거 극혐하므로, 여러가지 해본 결과 다음의 프로시저가 가장 아름답다는 결론이 났다.

===================================

CREATE procedure USP_CREATE_TABLE_SCRIPT
      @table_name SYSNAME
AS
BEGIN
--DECLARE @table_name SYSNAME
--SELECT @table_name = 'dbo.omm_config'

DECLARE
      @object_name SYSNAME
    , @object_id INT

SELECT
      @object_name = o.name
    , @object_id = o.[object_id]
FROM sys.objects o WITH (NOWAIT)
JOIN sys.schemas s WITH (NOWAIT) ON o.[schema_id] = s.[schema_id]
WHERE o.name = @table_name
    AND o.[type] = 'U'
    AND o.is_ms_shipped = 0

DECLARE @SQL NVARCHAR(MAX) = ''

;WITH index_column AS
(
    SELECT
          ic.[object_id]
        , ic.index_id
        , ic.is_descending_key
        , ic.is_included_column
        , c.name
    FROM sys.index_columns ic WITH (NOWAIT)
    JOIN sys.columns c WITH (NOWAIT) ON ic.[object_id] = c.[object_id] AND ic.column_id = c.column_id
    WHERE ic.[object_id] = @object_id
),
fk_columns AS
(
     SELECT
          k.constraint_object_id
        , cname = c.name
        , rcname = rc.name
    FROM sys.foreign_key_columns k WITH (NOWAIT)
    JOIN sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id AND rc.column_id = k.referenced_column_id
    JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = k.parent_column_id
    WHERE k.parent_object_id = @object_id
)
SELECT @SQL = 'CREATE TABLE ' + @object_name + CHAR(13) + '(' + CHAR(13) + STUFF((
    SELECT CHAR(9) + ', [' + c.name + '] ' +
        CASE WHEN c.is_computed = 1
            THEN 'AS ' + cc.[definition]
            ELSE UPPER(tp.name) +
                CASE WHEN tp.name IN ('varchar', 'char', 'varbinary', 'binary', 'text')
                       THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(5)) END + ')'
                     WHEN tp.name IN ('nvarchar', 'nchar', 'ntext')
                       THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(5)) END + ')'
                     WHEN tp.name IN ('datetime2', 'time2', 'datetimeoffset')
                       THEN '(' + CAST(c.scale AS VARCHAR(5)) + ')'
                     WHEN tp.name = 'decimal'
                       THEN '(' + CAST(c.[precision] AS VARCHAR(5)) + ',' + CAST(c.scale AS VARCHAR(5)) + ')'
                    ELSE ''
                END +
                CASE WHEN c.collation_name IS NOT NULL THEN ' COLLATE ' + c.collation_name ELSE '' END +
                CASE WHEN c.is_nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END +
                CASE WHEN dc.[definition] IS NOT NULL THEN ' DEFAULT' + dc.[definition] ELSE '' END +
                CASE WHEN ic.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(ic.seed_value, '0') AS CHAR(1)) + ',' + CAST(ISNULL(ic.increment_value, '1') AS CHAR(1)) + ')' ELSE '' END
        END + CHAR(13)
    FROM sys.columns c WITH (NOWAIT)
    JOIN sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
    LEFT JOIN sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id
    LEFT JOIN sys.default_constraints dc WITH (NOWAIT) ON c.default_object_id != 0 AND c.[object_id] = dc.parent_object_id AND c.column_id = dc.parent_column_id
    LEFT JOIN sys.identity_columns ic WITH (NOWAIT) ON c.is_identity = 1 AND c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
    WHERE c.[object_id] = @object_id
    ORDER BY c.column_id
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
    + ISNULL((SELECT CHAR(9) + ', CONSTRAINT [' + k.name + '] PRIMARY KEY (' +
                    (SELECT STUFF((
                         SELECT ', [' + c.name + '] ' + CASE WHEN ic.is_descending_key = 1 THEN 'DESC' ELSE 'ASC' END
                         FROM sys.index_columns ic WITH (NOWAIT)
                         JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
                      WHERE ic.is_included_column = 0
                             AND ic.[object_id] = k.parent_object_id
                             AND ic.index_id = k.unique_index_id
                         FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, ''))
            + ')' + CHAR(13)
            FROM sys.key_constraints k WITH (NOWAIT)
            WHERE k.parent_object_id = @object_id
                AND k.[type] = 'PK'), '') + ')'  + CHAR(13)
    + ISNULL((SELECT (
        SELECT CHAR(13) +
             'ALTER TABLE ' + @object_name + ' WITH'
            + CASE WHEN fk.is_not_trusted = 1
                THEN ' NOCHECK'
                ELSE ' CHECK'
              END +
              ' ADD CONSTRAINT [' + fk.name  + '] FOREIGN KEY('
              + STUFF((
                SELECT ', [' + k.cname + ']'
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
               + ')' +
              ' REFERENCES [' + SCHEMA_NAME(ro.[schema_id]) + '].[' + ro.name + '] ('
              + STUFF((
                SELECT ', [' + k.rcname + ']'
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
               + ')'
            + CASE
                WHEN fk.delete_referential_action = 1 THEN ' ON DELETE CASCADE'
                WHEN fk.delete_referential_action = 2 THEN ' ON DELETE SET NULL'
                WHEN fk.delete_referential_action = 3 THEN ' ON DELETE SET DEFAULT'
                ELSE ''
              END
            + CASE
                WHEN fk.update_referential_action = 1 THEN ' ON UPDATE CASCADE'
                WHEN fk.update_referential_action = 2 THEN ' ON UPDATE SET NULL'
                WHEN fk.update_referential_action = 3 THEN ' ON UPDATE SET DEFAULT'
                ELSE ''
              END
            + CHAR(13) + 'ALTER TABLE ' + @object_name + ' CHECK CONSTRAINT [' + fk.name  + ']' + CHAR(13)
        FROM sys.foreign_keys fk WITH (NOWAIT)
        JOIN sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
        WHERE fk.parent_object_id = @object_id
        FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)')), '')
    + ISNULL(((SELECT
         CHAR(13) + 'CREATE' + CASE WHEN i.is_unique = 1 THEN ' UNIQUE' ELSE '' END
                + ' NONCLUSTERED INDEX [' + i.name + '] ON ' + @object_name + ' (' +
                STUFF((
                SELECT ', [' + c.name + ']' + CASE WHEN c.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END
                FROM index_column c
                WHERE c.is_included_column = 0
                    AND c.index_id = i.index_id
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')'
                + ISNULL(CHAR(13) + 'INCLUDE (' +
                    STUFF((
                    SELECT ', [' + c.name + ']'
                    FROM index_column c
                    WHERE c.is_included_column = 1
                        AND c.index_id = i.index_id
                    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')', '')  + CHAR(13)
        FROM sys.indexes i WITH (NOWAIT)
        WHERE i.[object_id] = @object_id
            AND i.is_primary_key = 0
            AND i.[type] = 2
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
    ), '')

PRINT @SQL
--EXEC sys.sp_executesql @SQL
END


SP_HELPTEXT 대안 3 MSSQL과 ORACLE

아우 내가 SP_HELPTEXT 때문에 몇번이나 수정버전 내놓는지 모른다.

아주 학을 땐다 학을 때.

SP_HELPTEXT 의 문제가 그리드 라인으로 화면에 뿌려주다 보니

아래의 화면처럼 가끔씩 정렬구조가 엉망으로 되어버린다.

이것 때문에 정렬 잘 맞추어 놓았다가 자꾸 깨져서 다시 맞추고 다시 맞추고를 한 100번은 한거 같다.

그러다가 생각해보니 라인으로 표시되면 그럴 이유가 없다는 글을 한번 본거 같다.

??

이런 간단한 방법이 있다니???

그래서 바꾼거를 결과물로 찍으니

메세지 결과물에 이렇게 아름답게 나오는 것이다.

씨붕 내가 대체 이때까지 뭐한거여?

자 결과물 올린다.


CREATE procedure sp_helptext2
@objname nvarchar(776)
,@columnname sysname = NULL
as

set nocount on

declare @dbname sysname
,@objid int
,@BlankSpaceAdded   int
,@BasePos       int
,@CurrentPos    int
,@TextLength    int
,@LineId        int
,@AddOnLen      int
,@LFCR          int --lengths of line feed carriage return
,@DefinedLength int

/* NOTE: Length of @SyscomText is 4000 to replace the length of
** text column in syscomments.
** lengths on @Line, #CommentText Text column and
** value for @DefinedLength are all 255. These need to all have
** the same values. 255 was selected in order for the max length
** display using down level clients
*/
,@SyscomText    nvarchar(4000)
,@Line          nvarchar(4000)

select @DefinedLength = 4000
select @BlankSpaceAdded = 0 /*Keeps track of blank spaces at end of lines. Note Len function ignores
                             trailing blank spaces*/
CREATE TABLE #CommentText
(LineId int
 ,Text  nvarchar(4000) collate database_default)

/*
**  Make sure the @objname is local to the current database.
*/
select @dbname = parsename(@objname,3)
if @dbname is null
    select @dbname = db_name()
else if @dbname <> db_name()
        begin
                raiserror(15250,-1,-1)
                return (1)
        end

/*
**  See if @objname exists.
*/
select @objid = object_id(@objname)
if (@objid is null)
        begin
        raiserror(15009,-1,-1,@objname,@dbname)
        return (1)
        end

-- If second parameter was given.
if ( @columnname is not null)
    begin
        -- Check if it is a table
        if (select count(*) from sys.objects where object_id = @objid and type in ('S ','U ','TF'))=0
            begin
                raiserror(15218,-1,-1,@objname)
                return(1)
            end
        -- check if it is a correct column name
        if ((select 'count'=count(*) from sys.columns where name = @columnname and object_id = @objid) =0)
            begin
                raiserror(15645,-1,-1,@columnname)
                return(1)
            end
    if (ColumnProperty(@objid, @columnname, 'IsComputed') = 0)
        begin
            raiserror(15646,-1,-1,@columnname)
            return(1)
        end

        declare ms_crs_syscom  CURSOR LOCAL
        FOR select text from syscomments where id = @objid and encrypted = 0 and number =
                        (select column_id from sys.columns where name = @columnname and object_id = @objid)
                        order by number,colid
        FOR READ ONLY

    end
else if @objid < 0  -- Handle system-objects
    begin
        -- Check count of rows with text data
        if (select count(*) from master.sys.syscomments where id = @objid and text is not null) = 0
            begin
                raiserror(15197,-1,-1,@objname)
                return (1)
            end

        declare ms_crs_syscom CURSOR LOCAL FOR select text from master.sys.syscomments where id = @objid
            ORDER BY number, colid FOR READ ONLY
    end
else
    begin
        /*
        **  Find out how many lines of text are coming back,
        **  and return if there are none.
        */
        if (select count(*) from syscomments c, sysobjects o where o.xtype not in ('S', 'U')
            and o.id = c.id and o.id = @objid) = 0
                begin
                        raiserror(15197,-1,-1,@objname)
                        return (1)
                end

        if (select count(*) from syscomments where id = @objid and encrypted = 0) = 0
                begin
                        raiserror(15471,-1,-1,@objname)
                        return (0)
                end

   declare ms_crs_syscom  CURSOR LOCAL
        FOR select text from syscomments where id = @objid and encrypted = 0
                ORDER BY number, colid
        FOR READ ONLY

    end

/*
**  else get the text.
*/
select @LFCR = 2
select @LineId = 1


OPEN ms_crs_syscom

FETCH NEXT from ms_crs_syscom into @SyscomText

WHILE @@fetch_status >= 0
begin

    select  @BasePos    = 1
select  @CurrentPos = 1
    select  @TextLength = LEN(@SyscomText)

    WHILE @CurrentPos  != 0
    begin
        --Looking for end of line followed by carriage return
        select @CurrentPos =   CHARINDEX(char(13)+char(10), @SyscomText, @BasePos)

        --If carriage return found
        IF @CurrentPos != 0
        begin
            /*If new value for @Lines length will be > then the
            **set length then insert current contents of @line
            **and proceed.
            */
            while (isnull(LEN(@Line),0) + @BlankSpaceAdded + @CurrentPos-@BasePos + @LFCR) > @DefinedLength
            begin
                select @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) + @BlankSpaceAdded)
                INSERT #CommentText VALUES
                ( @LineId,
                  isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @AddOnLen), N''))
                select @Line = NULL, @LineId = @LineId + 1,
                       @BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0
            end
            select @Line    = isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @CurrentPos-@BasePos + @LFCR), N'')
            select @BasePos = @CurrentPos+2
            INSERT #CommentText VALUES( @LineId, @Line )
            select @LineId = @LineId + 1
            select @Line = NULL
        end
        else
        --else carriage return not found
        begin
            IF @BasePos <= @TextLength
            begin
                /*If new value for @Lines length will be > then the
                **defined length
                */
                while (isnull(LEN(@Line),0) + @BlankSpaceAdded + @TextLength-@BasePos+1 ) > @DefinedLength
                begin
                    select @AddOnLen = @DefinedLength - (isnull(LEN(@Line),0) + @BlankSpaceAdded)
                    INSERT #CommentText VALUES
                    ( @LineId,
                      isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @AddOnLen), N''))
                    select @Line = NULL, @LineId = @LineId + 1,
                        @BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0
                end
                select @Line = isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @TextLength-@BasePos+1 ), N'')
                if LEN(@Line) < @DefinedLength and charindex(' ', @SyscomText, @TextLength+1 ) > 0
                begin
                    select @Line = @Line + ' ', @BlankSpaceAdded = 1
                end
            end
        end
    end

    FETCH NEXT from ms_crs_syscom into @SyscomText
end

CLOSE  ms_crs_syscom
DEALLOCATE  ms_crs_syscom

IF @Line is NOT NULL INSERT #CommentText VALUES( @LineId, @Line )

/* ------------------------------ SCRIPT 정리 시작 ------------------------------ */

/* 줄 끝 공백과 탭 제거 */
declare @seq int
declare @text nvarchar(4000)
declare @crlf nvarchar(2)

DECLARE ScriptCursor1 CURSOR LOCAL FORWARD_ONLY STATIC FOR
    select LineId, Text from #CommentText order by LineId

OPEN ScriptCursor1

FETCH NEXT FROM ScriptCursor1 INTO @seq, @text

WHILE @@FETCH_STATUS = 0 BEGIN
    IF @text LIKE '%' + CHAR(13) + CHAR(10) BEGIN
        SET @text = SUBSTRING(@text, 1, LEN(@text) - 2)
        SET @crlf = CHAR(13) + CHAR(10)
    END ELSE BEGIN
        SET @crlf = ''  
    END
    SET @text = REVERSE(@text)
    WHILE 1 = 1 BEGIN
        IF CHARINDEX(CHAR(9), @text) != 1 AND CHARINDEX(CHAR(32), @text) != 1 BREAK
        IF CHARINDEX(CHAR(9), @text) = 1 SET @text = SUBSTRING(@text, 2, 4000)
        IF CHARINDEX(CHAR(32), @text) = 1 SET @text = SUBSTRING(@text, 2, 4000)
    END
    SET @text = REVERSE(@text) + @crlf
    UPDATE #CommentText SET [Text] = @text WHERE LineId = @seq
    FETCH NEXT FROM ScriptCursor1 INTO @seq, @text
END

CLOSE ScriptCursor1
DEALLOCATE ScriptCursor1

/* SCRIPT 끝 케리지 리턴 제거 */
SET @seq = NULL
SET @text = NULL

DECLARE ScriptCursor2 CURSOR LOCAL FORWARD_ONLY STATIC FOR
    select LineId, Text from #CommentText order by LineId DESC

OPEN ScriptCursor2

FETCH NEXT FROM ScriptCursor2 INTO @seq, @text

WHILE @@FETCH_STATUS = 0 BEGIN
    IF @TEXT != CHAR(13) + CHAR(10) BREAK

    DELETE #CommentText WHERE LineId = @seq

    FETCH NEXT FROM ScriptCursor2 INTO @seq, @text
END

CLOSE ScriptCursor2
DEALLOCATE ScriptCursor2

/* SCRIPT 앞 케리지 리턴 제거 */
SET @seq = NULL
SET @text = NULL

DECLARE ScriptCursor3 CURSOR LOCAL FORWARD_ONLY STATIC FOR
    select LineId, Text from #CommentText order by LineId

OPEN ScriptCursor3

FETCH NEXT FROM ScriptCursor3 INTO @seq, @text

WHILE @@FETCH_STATUS = 0 BEGIN
    IF @TEXT != CHAR(13) + CHAR(10) BREAK

    DELETE #CommentText WHERE LineId = @seq

    FETCH NEXT FROM ScriptCursor3 INTO @seq, @text
END

CLOSE ScriptCursor3
DEALLOCATE ScriptCursor3

/* ------------------------------ SCRIPT 정리 끝 ------------------------------ */

/* SCRIPT PRINT */
SET @seq = NULL
SET @text = NULL

DECLARE ScriptCursor9 CURSOR LOCAL FORWARD_ONLY STATIC FOR
    select LineId, Text from #CommentText order by LineId

OPEN ScriptCursor9

FETCH NEXT FROM ScriptCursor9 INTO @seq, @text

WHILE @@FETCH_STATUS = 0 BEGIN
    PRINT @text

    FETCH NEXT FROM ScriptCursor9 INTO @seq, @text
END

CLOSE ScriptCursor9
DEALLOCATE ScriptCursor9

DROP TABLE  #CommentText

return (0) -- sp_helptext



환경변수 명령어처리(Setx Path)를 중심으로

원래 환경변수는 아래의 것을 명령프롬프트에서 넣으면 된다.

setx -m JAVA_HOME "d:/jdk"
setx path "%PATH%;%JAVA_HOME%\bin" /m
setx -m ORACLE_HOME "d:\OraClient"
setx -m NLS_LANG "KOREAN_KOREA.KO16MSWIN949"
setx -m TNS_ADMIN  "d:\OraClient"

setx path "%PATH%;%ORACLE_HOME%" /m


그런데 퍽킹 저장이 안되는 거다.

무슨일인데 안되지 하면서 계속 쳐다봤는데...

문자열이 잘린다는 소리였다.

씨붕 환경변수들 보면 mssql이 엄청나게 글자쓰고, 인텔이 엄청써서 보니깐 쓸수 있는 문자열이 1024로 짤리다니...

화딱지나서 

setx -m JAVA_HOME "d:/jdk"
setx /M PATH "%JAVA_HOME%\bin;%PATH%"
setx -m ORACLE_HOME "d:\OraClient"
setx -m NLS_LANG "KOREAN_KOREA.KO16MSWIN949"
setx -m TNS_ADMIN  "d:\OraClient"
setx path "%PATH%;%ORACLE_HOME%" /m

이걸로 바꾸어서 Path 설정했다.

이건 보니까 setX 라는 명령어가 1024 문자열 이상을 지원 안하는 버그(?) 때문이었다.
어쩔수 없이 다음에는 컴터 설치하자마자 패스부터 설정하고 나머지를 깔던지 해야겠다.


자바는 소중하니깐요.


스토어드 프로시저로 table create 명령줄 뽑아내기. MSSQL과 ORACLE

이 sp를 실행하면 테이블 구조의 내용을 script로 뽑아준다.
맨날 mssm의 수정 부분들어가서 script생성 어쩌구 눌러서 만들려면 귀찮다.


결과물은 아래 그림을 참조.



--◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
--◆              (c) Copyright Brainnet Co..Ltd.  2005
--◆                   All rights reserved
--◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
--◆ Procedure Name :  SP_Z_GET_TABLE_CREATE
--◆ Program Code   :  SP_Z_GET_TABLE_CREATE
--◆ Description    :  table create 명령줄 뽑아내기.
--◆ Author         :  홍길동
--◆ Date           :  2016. 06. 29.
--◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
--◆ Modification Log
--◆
--◆ Date            In Charge    Description
--◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
--◆ 2014. 12. 16.   softone     Initial Release
--◆
--◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
CREATE PROCEDURE SP_Z_GET_TABLE_CREATE
(
      @P_TABLE_NAME                   nVarchar(100)
)
AS

BEGIN

    DECLARE @SQL TABLE(S VARCHAR(4000), ID INT IDENTITY)


    declare #ZSY_SYS_cur01 cursor for
      SELECT upper(name) o_name
        FROM sysobjects
       WHERE xtype = 'U'
       and name = @P_TABLE_NAME
       order by upper(name)
    OPEN #ZSY_SYS_cur01

    fetch next from #ZSY_SYS_cur01 into
                    @P_TABLE_NAME
    WHILE (@@fetch_status <> -1)
    BEGIN
        INSERT INTO  @SQL(S)
        SELECT 'CREATE TABLE ' + @P_TABLE_NAME + ' ('

        ;WITH AAA AS (
                SELECT OBJECT_NAME(o.parent_object_id) AS TABLE_NAME
                     , o.Name AS      CONSTRAINT_NAME
                     , cost_name.name COLUMN_NAME
                  FROM sys.objects o
                  JOIN sys.schemas s
                    ON o.schema_id = s.schema_id
                  JOIN sys.all_columns cost_name
                    ON o.object_id = cost_name.default_object_id
                   AND o.parent_object_id = cost_name.object_id
                 WHERE 1=1
                   AND o.type = 'D'
                   AND OBJECT_NAME(o.parent_object_id) = @P_TABLE_NAME

        )
        INSERT INTO @SQL(S)
        SELECT CASE WHEN ORDINAL_POSITION = 1 THEN '   ' ELSE ' , ' END
             + A.COLUMN_NAME
             + N' ' + DATA_TYPE +
                                  CASE WHEN CHARACTER_MAXIMUM_LENGTH > 0 THEN '(' + CONVERT(VARCHAR(MAX), CHARACTER_MAXIMUM_LENGTH) + ')'
                                       WHEN NUMERIC_PRECISION > 0 THEN '(' + CONVERT(VARCHAR(MAX), NUMERIC_PRECISION)+ ',' + CONVERT(VARCHAR(MAX), NUMERIC_SCALE) + ')'
                                       WHEN DATETIME_PRECISION > 0 THEN ''
                                  END
             + N' ' + ( CASE WHEN IS_NULLABLE = 'NO' THEN 'NOT ' ELSE '' END ) + 'NULL '
             + N' CONSTRAINT ' + CASE WHEN CONSTRAINT_NAME IS NULL THEN '' ELSE CONSTRAINT_NAME END
             + N' ' + CASE WHEN COLUMN_DEFAULT IS NULL THEN '' ELSE COALESCE('DEFAULT '+COLUMN_DEFAULT,'') END


          FROM INFORMATION_SCHEMA.COLUMNS A
          LEFT
          JOIN AAA B
            ON A.TABLE_NAME  = B.TABLE_NAME
           AND A.COLUMN_NAME = B.COLUMN_NAME
         WHERE A.TABLE_NAME  = @P_TABLE_NAME
         ORDER
            BY A.ORDINAL_POSITION
         ;
        INSERT INTO  @SQL(S)
        SELECT ' )'

        INSERT INTO  @SQL(S)
        SELECT ' ALTER TABLE ' + @P_TABLE_NAME + ' ADD CONSTRAINT ' + ' PK_' + @P_TABLE_NAME + N' PRIMARY KEY ' 
        ;WITH AAA AS (
                SELECT OBJECT_NAME(o.parent_object_id) AS TABLE_NAME
                     , o.Name AS      CONSTRAINT_NAME
                     , cost_name.name COLUMN_NAME
                  FROM sys.objects o
                  JOIN sys.schemas s
                    ON o.schema_id = s.schema_id
                  JOIN sys.all_columns cost_name
                    ON o.object_id = cost_name.default_object_id
                   AND o.parent_object_id = cost_name.object_id
                 WHERE 1=1
                   AND o.type = 'D'
                   AND OBJECT_NAME(o.parent_object_id) = @P_TABLE_NAME

        )
        INSERT INTO  @SQL(S)
         SELECT  CASE WHEN A.column_id = 1 THEN ' ( ' ELSE ' , ' END + INDEX_COL(@P_TABLE_NAME, A.INDEX_ID, A.INDEX_COLUMN_ID ) COL_NM
           FROM  sys.index_columns A
           JOIN  SYSINDEXES B
             ON  A.object_id = B.ID
            AND  B.INDID = A.INDEX_ID
          WHERE  A.object_id = OBJECT_ID( @P_TABLE_NAME )

        INSERT INTO  @SQL(S)
        SELECT ' )'
    fetch next from #ZSY_SYS_cur01 into
                    @P_TABLE_NAME
    END


    CLOSE #ZSY_SYS_cur01
    DEALLOCATE #ZSY_SYS_cur01

    SELECT * FROM @SQL

END

cross apply 셈플 MSSQL과 ORACLE

select * 
  from oqm_qc_category A
 where start_dt in ( select MAX(x.start_dt)
                       from oqm_qc_category x
                      where A.qc_category_cd = x.qc_category_cd )
   --and qc_category_cd = 'M170604542'

SELECT TA.*
FROM oqm_qc_category TA
   CROSS APPLY (SELECT TOP 1 * FROM oqm_qc_category TB
                             WHERE TB.qc_category_cd = TA.qc_category_cd
                              AND TB.start_dt <= TA.start_dt
                              ORDER BY start_dt DESC) TT
--where    TA.qc_category_cd = 'M170604542'


자바 및 오라클 환경설정 한방에 처리하기 MSSQL과 ORACLE

우선 오라클이랑 자바를 환경변수에 일일이 넣고 싶지 않으신 분들을 위하여 이 글을 바친다.


필자의 경우 오라클클라이언트랑 자바클라이언트를 항상 D드라이브에 설치한다.
왜냐면 다시 설치하기가 귀찮기 때문이다.


그래서 포멧하면 다시 환경설정 들어가서 Path치는 것이 너무나 싫다.

즉, 이거 타이핑하기가 귀찮다는 소리.


오라클 클라이언트 설치없이 쓰는 방법은 내 블로그 찾아보면 나올 것이다.
그걸 전제로 이야기를 풀어본다.

환경변수에 들어가서 일일이 클릭하고 치기가 귀찮으시면 cmd창 열어서

아래의 것을 치면 완성됨


setx -m JAVA_HOME "d:/jdk"
setx path "%PATH%;%JAVA_HOME%\bin" /m
setx -m ORACLE_HOME "d:\OraClient"
setx -m NLS_LANG "KOREAN_KOREA.KO16MSWIN949"
setx -m TNS_ADMIN  "d:\OraClient"

setx path "%PATH%;%ORACLE_HOME%" /m

폴더명칭이나 드라이브 명칭만 바꾸면 됩니다.


분산 트렌잭션 DTC, RPC 가 안되는 분들을 위한 트러블슈팅 (Windows Server 2012버전 중심으로) MSSQL과 ORACLE

젝일! 

최근 MS-SQL 두대를 링크드서버(linked-server) 를 통하여 연결한 후
분산트렌젝션을 했다.

그런데 조까튼 문제가 발생했다.

한놈은 Windows Server 2003 이고 
한놈은 Windows Server 2012 였다.


문제는 이 더러븐 놈의 셋팅이 예전에 할때는 잘 되었는데 이번에는 죽어도 안되는 거였다.

즉 서버 2003에서 이런식으로 작성해서 저장하면 




보안구성

요런식으로 넣으면 레지스트리의 
HKLM\SOFTWARE\Microsoft\Rpc\internet 부분에 저장이 된다. (아래화면 참조)

즉, 이 부분을 레지스트리에 넣으나, 프로그램으로 넣으나 같은 결과물을 가진다는 말이다.



그런데, Fucking 2013 서버는 
전혀 다른 메카니즘을 보이고 있었다는 것을 간과했다.


나는 예전에만 분산트렌젝션을 일으켰기 때문에 기억은 2003 서버 기준으로만 생각하고 있었다.

그런데,

일단 화면 부터 퍼킹 헬이다.


포트번호 넣고 MSDTC설정 해볼까? 했는데 

MSDTC가 여기에 없다.
즉, 여기에 있다.




보다 시피 옵션도 존나리 많다.

하지만, 이건 넘어가리라고 생각했다.

근데 Dtcping을 통하여 통신이 일어나지 않았다.

어떤 문서 보니깐 HKLM\SOFTWARE\Microsoft\Rpc 여기에다가 포트 넣으라고 되어있어서
씨붕 넣었다.

안되었다.

다시 internet 폴더에 



넣었다.


이게 무슨 개 삽질일까?


아마 인터넷폴더를 번역하면서 어떤 ㅂㅅ이 internet을 폴더라고 생각하지 않고 RPC폴더에 바로 넣는 것으로 착각했나 보다.



암튼 개삽질이었음.



정리해보자

1. RPC통신을 하려면 두 MSSQL 컴퓨터간에 컴퓨터이름으로 ping을 할수가 있어야 한다.

즉 CMD창(명령프롬프트)에서 ping xxx.xxx.xxx.xxx 가 아닌 A서버의 명칭 
 - 서버명칭은 제어판->시스템 에서 보면 나옵니다. - 

  즉, ping rpc서버1[가칭] 과 ping rpc서버2[가칭] 가 다 먹혀야 한다.
     이게 안먹힌다면, windows\system32\drivers\etc\hosts파일을 열어서 
     xxx.xxx.xxx.xxx  rpc서버1 을 추가하면 됩니다.
서버 재부팅 해주세요.
  
   이렇게 했는데도 안먹히면 분명히 firewall이 막혀있습니다.  
   네트웍 관리자에게 Ping 막혀있는지 물어보세요

2. RPC포트 열려있어야 합니다. 
   135번 포트입니다.
  이게 내부방화벽으로 막혀있을 수도 있고, 


아니면 네트웍 방화벽에도 막혀있을 수 있으니 네트웍 관리자에게 물어보세요


3. RCP가 내부적으로 사용하는 동적포트를 뚫어주어야 합니다.


그건 위에 다 설명되어 있습니다.




이후 DTCping.exe파일을 두 서버에서 동시에 실행한 후에


두 포트가 정상적으로 오는지 보고 통신이 왔다갔다 하는지를 보세요

한군데서 실행한 후에 다른데서 실행하면 두놈다 반응을 일으킵니다.
A서버에서 실행한 후 컴터이름을 치고 Ping을 했는데, B서버에서 반응이 없으면 RPC가 안되는 겁니다.


이게 되면 분산트렌잭션은 거의 100% 실행됩니다.

참조

http://nagid.egloos.com/2986380


오라클에서 MSSQL처럼 TOP 1 을 통하여 UPDATE하기

우선 http://nagid.egloos.com/3017597 이 게시물 참조.


SET SERVEROUTPUT ON;
BEGIN
                MERGE INTO hrap002 m 
                USING (SELECT rid, ROWNUM rn FROM (SELECT ROWID rid FROM hrap002
                                                    where emp_id = '10001'
                                                   ORDER BY appnt_dt desc, SEQ_NO desc)
                                            where ROWNUM = 1       
                                                   ) s 
                ON (m.ROWID = s.rid) 
                WHEN MATCHED THEN 
                UPDATE SET job_title_cd =  '11'
                
                ;   
          
    DBMS_OUTPUT.PUT_LINE( TO_CHAR(SQL%ROWCOUNT) || ' 줄 반영되었어..');
    DBMS_OUTPUT.PUT_LINE( TO_CHAR(etl.get_merge_insert_count) || ' 줄 추가되었어.');
    DBMS_OUTPUT.PUT_LINE( TO_CHAR(etl.get_merge_update_count( SQL%ROWCOUNT ))|| ' 줄 수정되셨어.');
                
END;

요런 방식으로 쓰면 자기가 원하는 방식으로 업데이트를 칠수 있음.
물론 이 방식으로 Insert도 할 수 있음.

최근에 고전 Xcom1 로 OpenXcom 을 해보았다. 게임?

1. OpenXcom은 두가지 버전 모두를 지원하니 이쪽도 해보고 저쪽도 해봐서 좋다.

일단 화면 투척



그지같은 외계인 비행접시 2대나 걸린 스크린샷이다.

이놈들 초반에 너무 강해서 보이자마자 몇방맞고 탱크 빈사상태다.

물론 이판은 내가 보이자마자 후퇴한 미션이다.


암튼 xcom1도 무지막지한 보정을 통해서 예전에 쉽게 끝내신분들도 한번 해보면 힘들거라고 생각한다.


물론 본인은 SuperHuman 에다가 철인모드(ironman - 저장은 자동으로되고 이전버전으로 로딩안됨. )


끝내기는 했다.


오랫만에 한거라서 초반에 태크트리 좀 꼬여서 실패(2번이나... 헉) 를 하기도 했지만 무난하게 끝낸거 같다.

간만에 불태웠음.


어라? 이미지들이 왜 올리면 다 짤리지?


최근에 고전 Xcom2 인 TFTD의 OpenXcom 을 해보았다. 게임?




일단 화면을 한번 보자

1. 일단 전체 해상도가 그래픽카드 지원되는 것 까지 다 지원한다.
   이 말은 즉, 예전에 갑갑한 정도의 화면이 보여줘서 스크롤이 존나 많이 발생했는데 이번 버전은 그래픽카드 지원까지로 크게 볼수있다. 덕분에 그래픽이 깔끔한 것 같은 느낌이 든다.
2. 난이도가 일부 변경되었다.
   본인은 원래 Xcom1은 시시하고 Xcom2는 초인난이도 즉, "Super Human" 이 아니면 안한다.
   그런데, 이번에 그냥 간단하게 생각하고 Super Human으로 했는데 개박살 났다. 그것도 2번이나.

   왜 그런고 하니, 처음에 원래 기술개발이 진행되지 않으면 3개월이내에는 기지로 처들어오지 않았다.
   그런데 이놈들 2개월 되니깐 처들어 온다.
   어떤때는 1개월에 처들어 올때도 있었다.
   아쿠아로이드인 초록색 최고 쉬운 놈 (섹토노이드 같은 놈)들만 처들어 올때는 상관 없는데,
   문제는 잠수복입은 놈과 같이 처들어오면 초반 공격형 무기가 낮을때는 죽일 수가 없다는 점이다.

   3방 4방 맞추면 죽일수 있을 것 같았지만, 데이지가 들쑥날쑥이라서 공격력이 너무 낮으면 공격차체가 무위로 돌아가는 시스템인거 같은데, 문제는 고폭수류탄을 3~4방 터뜨려도 멀쩡하다는 점이다. 물론 다른 것들의 무기도 마찬가지임.

최소한 "Sonic purser" 정도의 외계인 수류탄이나, 외계인무기 정도는 되야 안정적으로 딜을 할수 있는 관계로 기지침공미션에서 전멸했다. 탱크를 많이 모았어도 탱크로 부술수 없었다.
그리고 또한 데미지 보정이 많이 일어나서 예전에는 탱크만 있어도 초반미션은 어느정도 해결되었는데, 이번 버전은 탱크신공으로는 깨기가 불가능한 상황이 벌어졌다. 

암튼 그래서 초반에는 존나 힘들었다.

아~ 그리고 이놈들 이제 문도 잘따고 들어온다. 물론 엄청난 인공지능은 아니지만
적이 우리편 우주선 문을 따고 유도미사일로 우리편 전멸시키는 장면을 내가 목격했다. 와우~

암튼 이래저래 세이브를 통해서 마지막 미션만 남겨놓은 상태.


3. 여러가지 옵션을 통해 인터페이스가 엄청난 개선이 일어났다.
   이건 해보면 알겠네요.



암튼 옛날에 해보신 분들이라면 꼭 해보시고,
최근 버전의 Xcom 시리즈를 즐겨하셨던 분들이시라면 마음 단단히 먹고 해보세요.


1 2 3 4 5 6