<서론>

프로젝트 중 "java.sql.BatchUpdateException: 업데이트에 대한 결과 집합 이 생성되었습니다." 라는 오류 메시지가 콘솔창에 출력되었다.

처음 사용하는 프레임워크로 프로젝트를 진행하고 있기 때문에 프레임워크 문제인지도 많이 고민했었다.

혼자 고민해보고 이곳저곳 고쳐보다가 제발 있었으면 좋겠다 라는 심정으로 구글링한 결과, 해결책을 찾을 수 있었다.

 

역시 구글은 모든 걸 알고있다.

 

 


 

<본론>

1. sqljdbc4.jar 파일 문제

sqljdbc의 버전에 의해 문제가 발생할 수 있다는 글을 찾았다. 운영도 되고 있는 서비스라 sqljdbc 파일을 변경 후 검증가지 필요하므로 막무가내로 파일을 변경하기에는 조금 무리가 있어 최후의 수단으로 남겨두고 다른 방법을 찾았다.

 

2. 프로시저 내의 "NO COUNT ON"

프로시저의 "NO COUNT ON" 구문이 해당 문제를 야기한다는 글을 찾았다. 프로시저 마지막에서 리턴받을 데이터가 없는 처리용일 때는 해당 명령을 빼주면 오류가 발생하지 않는다고 한다.

일단 내 쿼리는 리턴값이 있었지만, 속는 셈 치고 해당 명령을 주석처리한 결과 오류는 해결되었다.

 

 


 

<결론>

엄밀히 말하면 완벽한 해결은 아니다. 위에 언급했듯이 내 프로시저에서는 리턴값이 있는 프로시저였음에도 위와 같은 오류가 발생했다. 정말 sqljdbc4.jar 파일 문제일 수도 있지만 아직 개발 초보라 NO COUNT ON이 정확히 어떤 명령어인지 파악하지 못했다.

NO COUNT ON 을 좀 더 공부해보고, 내 프로시저에 어떤 문제가 있었는지 분석한 다음 NO COUNT ON에 대한 정리글도 포스팅하겠다.

 

<참고자료>

https://blog.naver.com/PostView.nhn?blogId=lkssky2002&logNo=220477127663&proxyReferer=http%3A%2F%2Fwww.google.com%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D1%26ved%3D2ahUKEwjW0v3B05PnAhXMc3AKHYlyBhwQFjAAegQIAxAB%26url%3Dhttp%253A%252F%252Fm.blog.naver.com%252Flkssky2002%252F220477127663%26usg%3DAOvVaw08rR0Nv06OhNtsgJT1y43I

 

[해결]mssql 프로시져 호출시 "업데이트에 대한 결과 집합 이 생성 되었습니다" 오류 발생

java 비즈니스 로직에서 프로시져 호출시 "업데이트에 대한 결과 집합 이 생성 되었습니다" 라는 오류 메세...

blog.naver.com

 

<서론>

프로젝트에서 사용하던 DB가 MSSQL로 되어 있어서 MSSQL을 사용해볼 수 있었다. 그러다보니 문자열을 자르거나, 문자열을 찾거나 하는 등의 처리를 하는 일이 있었는데, 자주 쓰기보다 어쩌다 한 번 나오는 경우라 기억하지 못하고 계속 구글링으로 찾아봤다. 그렇게 계속 찾기엔 귀찮아서 내 블로그에 정리하려 한다. 앞으로는 내 블로그 봐야지 히힛.

 

 


 

<본론>

1. 문자 길이 확인 (LEN, DATALENGTH)

1-1. 글자 수 확인

LEN( string_expression ) / return int
ex) LEN( 'Hello' ) / return 5

하지만 LEN은 자료형이 CHAR, VARCHAR인 경우에 사용할 수 있다(N이 붙어도 가능). 이 점을 잊고 쿼리를 짜다간 깊은 혼란에 빠질 수 있다.

 

1-2. byte 수 확인

DATALENGTH( expression ) / return int
ex) DATALENGTH( 'Hello' ) / return 5

입력 변수에 TEXT나 NTEXT 등도 올 수 있으며 심지어 IMAGE도 가능하다고 한다.

Byte를 체크하기 때문에 한글인 경우에는 글자 수보다 크게 나온다.

 

2. 문자열 자르기(LEFT, RIGHT, SUBSTRING)

2-1. 문자 앞(왼쪽)에서부터 자르기

LEFT( string_expression, integer_expression ) / return (varchar or nvarchar)
ex) LEFT( '123456', 3 ) / return '123'

자르기를 원하는 문자열을 첫번째 파라메터로 넣고, 몇글자 자를 건 지 숫자를 두번째 파라메터로 넣는다.

입력하는 문자열은 varchar, nvarchar, char, nchar 만 가능하다. text나 ntext는 사용할 수 없다.

입력하는 문자열이 유니코드인 문자 데이터 형식인 경우 nvarchar를 return

입력하는 문자열이 유니코드가 아닌 문자 데이터 형식인 경우 varchar를 return

 

2-2. 문자 뒤(오른쪽)에서부터 문자 자르기

RIGHT( string_expression, integer_expression ) / return (varchar or nvarchar)
ex) RIGHT( '123456', 3 ) / return '456'

문자 앞에서부터 자르는 방식과 동일하다.

 

2-3. 중간부터 자르기

SUSBSTRING( expression, start, length ) / return (varchar or nvarchar or varbinary)
ex) SUBSTRING( '123456', 3, 2 ) / return '34'

입력받은 문자열의 중간을 잘라낼 때 사용. 시작값은 0이 아니라 1이다.

입력할 수 있는 데이터 형식은 char, binary, text, image가 가능하다.

입력값의 데이터 형식에 따른 리턴값의 데이터 형식은 다음과 같다.

char, varchar, text / return varchar

nchar, nvarchar, ntext / return nvarchar

binary, varbinary, image / reutnr varbinary

 

3. 숫자형인지 확인(ISNUMERIC)

ISNUMERIC( expression ) / return int
ex) ISNUMERIC( '123456' ) / return 1
ex2) ISNUMERIC('123k456') / return 0

입력한 문자열이 숫자형으로 변환이 가능한 지 확인하는 함수.

입력한 문자열이 숫자형으로 변환이 가능한 경우 1을 불가능한 경우에는 0을 반환한다.

 

4. 문자열 치환(REPLACE)

REPLACE( string_expression, string_pattern, string_replacement ) / return (varchar or nvarchar)
ex) REPLACE( '123456789123', '123', 'test' ) / return 'test456789test'

문자열 치환은 텍스트 에디터에서 쓰는 기능과 동일하다. 다만 하나만 바꾸는 것이 아니라 찾은 패턴은 모두 치환해 버린다.

입력한 문자열이 varchar나 nvarchar의 최댓값을 초과하는 값이라면 반환값을 8,000 byte에서 자른다.

 

5. 문자열 찾기(CHARINDEX, PATINDEX)

CHARINDEX( expression_to_find, expression_to_search [, start_location] ) / return (varchar or bigint or int)
ex) CHARINDEX( '123', '123456789123' ) / return 1
ex2) CHARINDEX( '123', '123456789123', 2) / return 10

처음 입력값을 두번째 입력한 값 내에서 찾고 첫번째 위치를 반환하는 함수. 세번째 입력 값으로 검색하는 위치를 조정할 수도 있다. 찾는 값이 없을 경우, 0을 반환한다.

 

5-1. 패턴 처음 위치

PATINEDX( '%pattern%', expression ) / return (varchar or nvarchar or bigint or int)
ex) PATINDEX( '%123%', '123456789123' ) / return 1
ex) PATINDEX( '123', '123456789123' ) / return 0

CHARINDEX와 비슷하지만 패턴을 LIKE 처럼 찾는다. CHARINDEX와 마찬가지로 찾는 패턴이 없을 경우 0을 반환한다.

 

6. 문자열 끝의 공백 지우기(LTRIM, RTRIM)

6-1. 문자 앞(왼쪽) 공백 지우기

LTRIM( character_expression ) / return (varchar or nvarchar)
ex) LTRIM( '        he llo  ') / return 'he llo  '

문자 앞(왼쪽)에 있는 공백을 제거하는 함수. 문자 끝(오른쪽)이나 중간의 공백은 제거하지 않는다.

 

6-2. 문자 뒤(오른쪽) 공백 지우기

RTRIM( character_expression ) / return (varchar or nvarchar)
ex) LTRIM( '        he llo  ') / return '        he llo')

문자 앞(왼쪽)에 있는 공백을 제거하는 함수. 문자 끝(오른쪽)이나 중간의 공백은 제거하지 않는다.

 

번외. 문자열 어디에 있든 공백을 한꺼번에 지울 땐 REPLACE를 사용

 

7. 공백 넣기(SPACE)

SPACE( integer_expression ) / return varchar
ex) SPACE( 3 ) / return '   '

입력한 숫자만큼 공백을 반환하는 함수. 만약 숫자가 음수라면 Null 을 반환한다.

 

번외. 유니코드 데이터에 공백을 포함하거나 8,000개가 넘는 공백을 반환하려면 SPACE 대신 REPLICATE를 사용

 

8. ASCII 코드 변환(ASCII, CHAR)

ASCII( character_expression ) / return int
CHAR ( integer_expression / return char
ex) ASCII( 'A' ) / return 65
ex2) CHAR( 65 ) / return 'A'

ASCII와 문자로 변환하는 함수.

CHAR와 관련해서는 몇 가지 제어 문자를 삽입할 수 있다.

 

CHAR(9)   : 탭

CHAR(10: : 줄바꿈

CHAR(13) : 캐리지 리턴

 

9. 대소문자 변환(UPPER, LOWER)

UPPER( character_expression ) / return (varchar or nvarchar)
LOWER( character_expression ) / return (varchar or nvarchar)
ex) UPPER( 'AbcdE' ) / return 'ABCDE'
ex2) LOWER( 'AbcdE' ) / return 'abcde'

입력받은 문자열을 모두 대문자 혹은 소문자로 변경하는 함수. 대소문자가 섞여있는 문자열을 비교할 때, 대문자 혹은 소문자로 맞추기 위해 사용하기도 한다.

 

10. 문자 반복(REPLICATE)

REPLICATE( string_expression, integer_expression ) / return (string_expression과 같은 형식)
ex) REPLICATE( '0', 4 ) / return '0000'

원하는 문자열을 원하는 횟수만큼 반복하는 함수. 숫자로 이루어진 데이터의 앞에 원하는 만큼 0을 넣어 자리를 맞춰주는 데 쓰일 수 있다.

 

11. 문자열을 반대로(REVERSE)

REVERSE( string_expression ) / return (varchar or nvarchar)
ex) REVERSE( 'abcdEABcdeFg' ) / return 'gFedcBAEdcba'

입력한 문자열을 거꾸로 반환하는 함수. 대소문자도 당연히 구분한다.

 


 

<결론>

문자열과 관련된 내장함수가 적진 않지만 자주 쓴다면 못 외울 것도 없다. 하지만 이렇게 많은 종류를 어쩌다 한 번씩 쓰니 일일히 외우고 다니기엔 여간 귀찮은 일이 아니다. 그리고 이번 프로젝트가 끝난다면 언제 또 MSSQL을 만나게 될지도 알 수 없다. 오라클 열심히 하자.

 

 

<참고자료>

1. https://docs.microsoft.com/ko-kr/sql/t-sql/language-reference?view=sql-server-ver15

<서론>

자바로 개발 중, ConcurrentModificationException이 발생했다. set을 사용할 때 나온 exception인데, 거의 처음 만난 exception이라 당황했다. 대충 찾아보니 동시성 문제라고 한다. set을 iterator에서 불러서 iterator.hasNext()를 while문 조건으로 넣어놓고 set을 수정했더니 이런 문제가 발생했다.


 

 

<본론>

set을 하나 복사해서 하면 될거라고 생각했다. 하지만 set이 깊은 복사가 되어서 복사한 set을 수정해도 원본의 set이 수정되었다. 결국 깊은 복사가 아닌 얕은 복사로 해당 문제를 해결하였다.

아래는 이해를 돕기 위한 코드이다.

 

1) 깊은 복사인 경우. (이때는 ConcurrentModificationException이 발생)

1
2
3
4
5
6
Set<Integer> tmpSet = set;
tmpSet.addAll(set);
Iterator<Integer> it = tmpSet.iterator();
while(it.hasNext()) {
    set.add(it.next()+num);
}
cs

 

2) 얕은 복사인 경우.(addAll( )을 이용하여 얕은 복사)

1
2
3
4
5
6
Set<Integer> tmpSet = new HashSet<Integer>(); 
tmpSet.addAll(set);
Iterator<Integer> it = tmpSet.iterator();
while(it.hasNext()) {
    set.add(it.next()+num);
}
cs

 

 

<결론>

굉장히 간단하고 쉬운 문제지만, 갑자기 Exception을 마주하니 당황하게 되었다. 평소 깊은 복사, 얕은 복사 별 생각없이 개발했었는데, 이런 문제를 겪어보면서 실력있는 개발자가 되기에는 갈 길이 멀다고 느꼈다. 이런 문제들도 미리 생각해서 개발하는 참 개발자가 되어야겠다.(갑자기 분위기 일기)

<서론>

프로젝트 진행 중, 전날까지 잘되던 프로젝트가 서버 구동만 하면 콘솔에 어떤 글자가 써지기도 전에 오류 메시지창이 뜨면서 서버가 시작도 하지 않는 것이다. 잘되다가 갑자기 왜 그럴까 하고 구글링.. 비슷한 에러들은 많이 보이지만 나와 같은 에러는 없었다. 아마 "프롤로그에서는 콘텐츠가 허용되지 않습니다" 라는 말이 한글이라 검색결과가 잘 안나온 것 같아 이 부분을 "Content is not allowed in prolog" 로 바꾸고 검색했더니 스택오버플로우에 나왔다. 스택오버플로우 분들 감사합니다.


 

 

<본론>

헛소리는 이쯤하고 해결법부터 적어본다.

1. Eclipse 종료
2. [workspace]/.metadata/.plugins/org.eclipse.wst.server.core 폴더로 이동
3. tmp# 폴더를 삭제(#에는 번호가 들어간다. 예. tmp0, tmp1)
4. Eclipse 실행
5. tomcat, project clean

이렇게 했더니 처음처럼 아주 잘 돌아간다.


 

 

<결론>

tmp 폴더 내의 xml 파일이 꼬여서 그런 것 같기때문에 tmp 폴더를 그냥 다 날림으로써 해결했다. 매우매우 간단한 문제였는데, 한글로 검색하니 안나오고, 영어로 검색하니 나와서 다행이었다. 순간적으로 '영어로 검색해보자!' 라는 생각을 안했다면 아마 하루종일 고생했겠지..

다시한번 스택오버플로우 회원들에게 감사한다.

 

 

<참조>

https://stackoverflow.com/questions/36196734/removing-obsolete-files-from-server-could-not-clean-server-of-obsolete-files

 

Removing obsolete files from server... Could not clean server of obsolete files: Content is not allowed in prolog

I am creating a project which is in jsp,servlet and tomcat v 8.0.upto last night it works fine but today it didn't work it gives error in publishing tomcat server,please give me any suggest...

stackoverflow.com

 

ISNULL( SUM( column ), 0 ) - 권장

SUM( ISNULL( column, 0 ) ) - 이건 성능 저하. 무의미한 함수 발생

 

Null값은 연산을 하지 않으니 굳이 NVL 혹은 ISNULL 필요 없음

 

Oracle에서는 공백('')은 null 취급하지만

MSSQL에서는 공백과 null이 다르다... 이거 주의하자!

 

 

2020.01.31 추가

Null 값은 비교할 수 없다.

예)CASE WHEN A.col = '0' THEN ...

예2) CASE WHEN ISNULL(A.col, '0') = '0' THEN -- orcale : NVL(A.col,'0')

예)와 같은 쿼리에서 많약 A.col에 Null 값이 있다면 해당 조건은 무조건 false를 반환.

예2)와 같이 Null을 처리해줘야 CASE 문이 원하는데로 작동한다.

 

A.col = Null - 잘못된 방식

A.col IS NULL - 올바른 방식

 

A.col <> Null - 잘못된 방식

A.col IS NOT NULL - 올바른 방식

 

위에도 가끔 실수한다. 잘 고치자.

 

 

MAX( ISNULL( A.col, 0 ))

ISNULL( MAX( A.col ), 0)

큰 차이는 없지만 가끔 값이 다를 수 있다. Null 처리할 땐 조심하자

해당 내용은 내가 사용하려고 백업 용도로 올리는 글이다.

설명이나 이런 건 없다...

 

 

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM SYS.TABLES
WHERE OBJECT_ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS
WHERE NAME = 'APPL_TOT_DLV_AM')

SET

 

1.     Select 쿼리 결과갑을 입력하지 않고 직접 변수에 값을 입력하는 경우

2.     Null 결과 값을 입력하는 경우

3.     여러 변수 타입의 결과값을 입력하고 사용하는 경우

 

SELECT

 

1.     한 번에 여러 변수값을 할당하는 경우

 

2.     쿼리 결과 값 즉, 하나 이상의 값을 할당하는 경우

 

3.     @@ROWCOUNT, @ERROR를 사용하는 경우

 

<서론>

프로시저에 비즈니스 로직이 녹아있는 프로젝트를 하다보니 여러 프로시저 안에서 다른 프로시저를 부르는 경우를 많이 봤다. 그런데 간혹 프로시저 말고, 사용자 정의 함수를 호출하는 경우도 보였는데, 갑자기 사용자 정의 함수는 왜 쓰는 건지 궁금해졌다. 계속 프로시저만 써도 될 것 같은데 어째서 사용자 정의 함수를 쓰는 걸까? 

 


 

<본론>

프로시저와 사용자 정의 함수 모두 호출하게 되면 미리 정의 해놓은 기능을 수행하는 프로그램들이다. 인터넷에서 쉽게 찾을 수 있는 이 둘의 차이점이라면 아마 리턴 값인 것 같다.

프로시저는 리턴값이 없어도 되지만, 사용자 정의 함수는 꼭 있어야 한다.
또한 프로시저는 리턴값이 하나가 아닌 여러 개로 나와도 되지만, 함수는 오직 하나의 값만 있어야 한다.

인터넷에서 찾은 답은 이해하기는 쉬웠지만 와닿지는 않았다. 왜냐, 정말 차이가 저것뿐이라면 굳이 사용자 정의 함수를 쓸 필요가 없기때문이다. 프로시저로 사용자 정의 함수가 할 수 있는 일을 다 할 수 있는데, 굳이 둘을 섞어가며 쓸 이유는 없을 것이다. 그래서 좀더 인터넷을 찾아 봤다. 찾은 답은 다음과 같다.

 

프로시저 사용자 정의 함수
업무를 맡기는 목적 로직을 도와주는 목적
SP 안에 트랜잭션을 사용할 수 있음 사용자 정의 함수 안에 트랜잭션을 사용할 수 없음
파라미터 형식이 입,출력임 입력 파라미터만 가능
프로시저 안에서 다른 프로시저를 호출할 수 있음 사용자 정의 함수 안에서 프로시저를 호출할 수는 없음
SELECT, WHERE, HAVING 절에 프로시저를 사용할 수 없음 SELECT, WHERE, HAVING 절에 사용자 정의 함수를 사용할 수 있음
try-catch 블럭을 사용할 수 있음 try-catch 블럭을 사용할 수 없음

 

위 표와 같이 정리할 수 있는데, 특별히 굵게 처리된 부분이 사용자 정의 함수를 쓰는 이유의 핵심인 것 같다. 사실 표만 보면 프로시저는 되는데, 사용자 정의 함수는 안되는 것들이 무척이나 많다. 하지만 그 중 유일하게 가능한 것이 SELECT 쿼리 안에서는 사용자 정의 함수만 사용 가능하다는 점인 것 같다.

 


 

<결론>

배움이 부족하여 위와 같이 밖에 알아내지 못했다. 영어 실력이 좋았다면 영어로 된 문서들도 참고하면서 공부했을테지만, 한글도 제대로 못읽는 관계로 이정도로 마무리 지으려 한다.

 

<참고자료>

자료 출처를 적어놓지 못했다.. 원작자분들 죄송합니다.

'IT 공부 > 이론 공부' 카테고리의 다른 글

[DB]RAC, HA가 뭐지?  (3) 2019.03.20
[기본] SP(Stored Procedure - 저장 프로시저)  (1) 2019.03.04

<서론>

프로젝트를 진행하면서 RAC와 HA라는 말을 듣게 되었다. 개발 지식 및 상식은 없다시피한 초보 코더라서 그 자리에서는 못알아들었지만 그저 웃으며 고개를 끄덕였다. DB 관련 용어라 앞으로도 많이 마주할 것 같아 이렇게 따로 정리해보려고 한다. 블로그에 있는 나의 대부분의 글들이 그러하듯 이 글 역시도 인터넷에 돌아다니는 내용을 내 입맛대로 짜깁기 한 것이라 매우매우 부정확한 내용임을 미리 경고해둔다.




<본론>


HA와 RAC 모두 DB 서버의 구성에 관한 것이고, 고가용성을 위해 만들어진 구성이라는 것


처음 RAC와 HA를 들었을 때, 완전히 다른 두 개념인 줄 알았다. 하지만 조금 찾아보니, HA 구성이 먼저 나왔고 HA에서 몇가지를 보완한 것이 RAC라는 것을 알았다(아, 물론 RAC 이전에 OPS라는 것도 있었지만 그건 넘어가도록 하자).


우선 HA.

HA(High Availability)는 2개의 서버를 이용하여 하나는 Active 상태, 나머지 하나는 Standby 상태로 정해놓는다. 거의 모든 부하는 Active에서 부담하고 Standby 상태의 서버는 Active 서버가 장애가 발생하지 않는 이상, 거의 가동하지 않는다. 실제 서비스를 운영하는 Active 서버가 어떠한 장애로 정상적인 작동이 불가능해진다면, 곧바로 Standby 서버가 Active 되면서 다시 서비스를 정상 작동할 수 있게 하는 구성이다.

이해하기 쉬운만큼 구조도 단순하고 따라서 구축 비용도 저렴하다. 또한, 서버 하나만 가동되면 되므로 유지비 역시 저렴하다는 장점이 있다.

하지만, 몇가지 문제점이 있다. 각 서버 별로 별도의 storage를 가지고 있기 때문에 수시로 동기화가 이루어져야 하고, 따라서 성능 저하를 야기할 수 있다. 또한 이런 특성 때문에 각 서버간 데이터 싱크가 맞지 않는 상황도 존재할 수 있다. 마지막으로 굉장히 큰 문제인데, Active 서버가 동작을 멈추면 Standby 서버가 활성화 될 때까지의 트랜잭션을 모두 유실하게 된다는 것이다. 이는 실시간 트랜잭션량이 많은 서비스에서는 치명적인 문제이다.


그렇다면 HA에서 더 보완을 한 RAC는 어떨까?

RAC(Real Application Cluster)는 2개, 혹은 그 이상의 인스턴스가 하나의 storage를 바라보고 있는 구성이다. 각각의 인스턴스를 서버라고 생각하고 HA와 비교한다면 Active, Standby가 아닌 모두 Active 상태라고 할 수 있다. 그리고 모두 하나의 storage를 바라보는 상황이므로 별도의 동기화로 인한 성능 저하는 없다. 또, 하나의 인스턴스에서 장애가 발생해도 곧바로 다음 인스턴스에서 처리해줄 수 있으므로 데이터 유실에 대한 우려도 없다. HA에서는 하나의 서버가 모든 처리를 해야했으므로 상대적으로 큰 부하가 발생하지만, RAC 구성에서는 균형있게 분산되어 처리할 수 있다.

하지만, 이 역시도 단점이 존재한다. 우선 Oracle RAC가 매우 고가의 제품이라는 것이다. 또한 매우 복잡한 환경 구성으로 인해 유지보수 절차 역시도 복잡하며, 운영 인력은 RAC에 대한 충분한 이해도 필수이다. HA구조보다 빠른 복구 시간을 보장하지만, 실제로는 RAC 구조를 다루는데 미숙해서 복구시간을 연장시킬 가능성도 있다.




<결론>


HA : Acitve-Standby 구조. 비용이 적게 들고 간단하지만, 데이터 동기화 문제와 장애 발생 시, 정보 유실 우려

RAC : 여러 인스턴스가 하나의 Storage를 바라보는 구조. HA에 비해 성능과 안정성 모두 뛰어나지만, 비용이 많이 들고 다루기 어려움


장황하게 적어놨지만 결론은 이렇다!

사실 표를 그리거나 이해하기 좋은 그림을 넣고 싶었지만, 이런 막글을 누가 본다고 정성을 쏟을까.. 나중에 내가 다시 볼때 알아보기 쉽게 볼드 처리만 해놔야겠다.



<참조>

1. https://sksstar.tistory.com/63

2. http://blog.naver.com/PostView.nhn?blogId=dark009&logNo=150171352412

3. http://www.dator.co.kr/dataworld/textyle/42729

4. https://codelib.tistory.com/23


그리고 이건 그냥 참고하면 좋을 것

https://irkim.tistory.com/entry/HA%EC%99%80-RAC%EC%99%80%EC%9D%98-%EB%B9%84%EA%B5%90

1. 변수 사용

구글링 결과 제일 많이 나온 방법.. 잠깐 쓰고 버릴 변수를 만들고 그 변수로 ROW_NUMBER() 뒤에 오는 OVER() 조건에 넣어줬다.


1
2
3
4
DECLARE @RN INT = 1;
SELECT ROW_NUMBER() OVER(ORDER BY @RN) AS ROWS
       , *
  FROM [TABLE_NAME];

이것이 그 쿼리...

DECLARE 부터 통째로 MyBatis 쿼리 xml 파일에 넣었다.

그랬더니 깔끔하게 동작!


2. 서브 쿼리 사용

OVER()의 조건에 상수가 들어가지 않는다는 것이 문제였는데.. 생각하다보니 서브쿼리를 넣으면 어떻게 될까 궁금했다.


1
2
3
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS ROWS
       , *
  FROM [TABLE_NAME];


결과는 성공. 결국 상수 직접은 아니면서 1이기만 하면 다 되는 것 같다.




깨알팁.. 잊어버리지 않기 위해 블로그에 정리해서 올린다. 다음에도 MSSQL 쓸일이 있겠지.....


+ Recent posts