'프로그래밍'에 해당되는 글 198건
- 2006.04.14 C++ 에서 ADO 사용하기 11
- 2006.03.31 부분유니크한 값삽입. 11
- 2006.03.30 MAX + 1 , lock , 그리고 sp 3
- 2006.03.03 precompiled header 문제 2
- 2006.02.11 최대값얻기.. top 1 과 max() 2
- 2006.02.08 ' 문자를 처리하자 2
- 2006.01.24 db에러 체크 BeginTrans 11
- 2006.01.19 activex DLL 만들기. 맨날 까먹는거 13
http://redrebel.egloos.com/1717186 <-예전에 올렸던 방법
고수님이 도와주셔서 제가 먼저 등록했던 방법을 고쳤습니다.
정말 깔끔하게 떨어지더군요^^;
구현하려고하는 기능과 해야될 조건들은 예전의 글을 참조하세염.
방법은 테이블하나를 더 추가하여 하나의 레코드에 하나의 컬럼만을 생성한다.
CREATE TABLE [dbo].[ex_no_TBL] (
[idx] [int]
GO
이테이블에 sp가 접근을 하는데 sp는 테이블의 레코드를 1씩증가시키며 6500 이 넘으면 다시 1로 바뀌는 역활을한다.
CREATE PROC [dbo].[get_fileno]
--로컬변수 선언
@TextMaxNum int output
as
set nocount on
begin tran
update ex_no_TBL set idx = (case when idx+1 > 6500 then 1 else idx+1 end)
select @TextMaxNum=idx from flashmall_user.dbo.ex04
commit tran
RETURN(@TextMaxNum)
GO
asp 페이지에서 sp를 호출한다음에 @TextMaxNum 를 리턴받는다.
Set cmd = server.CreateObject("ADODB.command")
With cmd
.ActiveConnection = db 'open된 db
.CommandType = 4 'adCmdStoredProc 입니다. sp 접근시... 1는 text입니다.
.CommandText = "get_fileno"
.Parameters.Refresh
.Execute
End With
dim file_no
file_no = cmd.Parameters("@TextMaxNum").Value
sqlString = "insert into ex_TBL(c1,id) values("&file_no&",'"&id&"')"
db.execute sqlString
id 는 유저아이디입니다.
고수님이 도와주셔서 제가 먼저 등록했던 방법을 고쳤습니다.
정말 깔끔하게 떨어지더군요^^;
구현하려고하는 기능과 해야될 조건들은 예전의 글을 참조하세염.
방법은 테이블하나를 더 추가하여 하나의 레코드에 하나의 컬럼만을 생성한다.
CREATE TABLE [dbo].[ex_no_TBL] (
[idx] [int]
GO
이테이블에 sp가 접근을 하는데 sp는 테이블의 레코드를 1씩증가시키며 6500 이 넘으면 다시 1로 바뀌는 역활을한다.
CREATE PROC [dbo].[get_fileno]
--로컬변수 선언
@TextMaxNum int output
as
set nocount on
begin tran
update ex_no_TBL set idx = (case when idx+1 > 6500 then 1 else idx+1 end)
select @TextMaxNum=idx from flashmall_user.dbo.ex04
commit tran
RETURN(@TextMaxNum)
GO
asp 페이지에서 sp를 호출한다음에 @TextMaxNum 를 리턴받는다.
Set cmd = server.CreateObject("ADODB.command")
With cmd
.ActiveConnection = db 'open된 db
.CommandType = 4 'adCmdStoredProc 입니다. sp 접근시... 1는 text입니다.
.CommandText = "get_fileno"
.Parameters.Refresh
.Execute
End With
dim file_no
file_no = cmd.Parameters("@TextMaxNum").Value
sqlString = "insert into ex_TBL(c1,id) values("&file_no&",'"&id&"')"
db.execute sqlString
id 는 유저아이디입니다.
이틀을 고생하여 알아낸(알아낸건 아니구 또 삽질에 의한 방법 or 노하우 : 더 좋은 방법이 있음 알려주세요)
방법을 이곳에 기록합니다.
일단 이슈는...
대략 이렇습니다.
기존에 레코드에 새로운 데이터를 insert 한다.
그리고 그 insert 한 값을 알아낸다...
머 그리 어려운것도 아니네 하겠지만
이번에 제가 해야만 하는 프로그래밍에는 여러가지 제악조건이 있었습니다.
1. 특정 컬럼이 부분 유니크 해야한다.
이말이 먼말이냐하면 예를 들어 file_no 라는 컬럼이 1 부터 6500 까지 중복된 값이 없어야합니다.
insert 할때 file_no 값이 1부터 6500 까지 자동증가해야합니다.
중복된 값이 없어야하고 만일 6500 까지 되었으면 다시 1부터 시작해야합니다.
그러기 위해서는 insert 전에 select 를 하여서 마지막 값을 알아야합니다.
머 그리 어렵지 않게 어떻게 해야하는지 그림이 그려지는 분들도 있을것입니다.
select top 1 file_no from ex_TBL order by idx desc
(idx는 자연증가하는 컬럼)
file_no = file_no +1
if file_no > 6500 then
file_no = 1
end if
insert ex_TBL(file_no) values(file_no)
이런식으로요..
다음 조건을 보시죠...ㅡㅡ;
2.여러사람이 동시에 접속하는경우도 대비해야한다.
한거번에 여러사람이 몰리면
select 문이 실행되서 insert 문이 실행되기전에
또다른 select 문이 실행되어버려서
같은 값을 가질수있게됩니다.
그럼 중복된 값이 inser될수 있겠죠?
lock 를 생각하시는 분이 있으실것입니다.
오케이 일단 넘어가겠습니다.
3.입력된 file_no 가 과연 무엇이 들어갔는지 알아야된다.
사실 file_no는 화일명을 정하는 값이라서 그값을 가지고
서버에 화일을 저장해야합니다.
여러분이 그래야되는것이 아니라 제가 해야할것이 그랬다구요..ㅜ.ㅜ;
머 이것만 때서 생각해보면
다시 select 문을 써서 알아내면 되지 않느냐고 말하시는 분들이 있을겁니다.
이것도 일단 오케이....
자자자 이제 위에 조건들을 모아보면...머리가 아파오기 시작할겁니다.
물론 아니신 고수분들도 있을겁니다...ㅜ.ㅜ;
그럼 제가 이것을 어떻게 처리했는지 기록하겠습니다.
일단 select 문 2개와 insert문 1개가 동시에 처리되어야합니다.
당근 trans 를 생각하시겠죠?
db.begintrans
.
.
.
db.committrans
하지만 이것만으론 잘안되더군요.
어떻게 테스트를 했냐면요.
100번정도 for 문으로 막 돌린 asp 페이지를 여러브라우저에 띄워 한거번에 리플래쉬를 해봤습니다.
쿼리를 던지고 받는 시간을 줄이기위하여 sp 를 사용하였습니다.
중복되는 비율은 적어졌지만 여전히 중복데이타가 나오는 현상이 있었습니다.
이번에는 select 문 1개와 insert 문 1개 그리고 비교구분 1개를 하나의 쿼리로 만들었습니다.
(위에 1.번을 참조)
insert into ex_TBL(file_no,id) select top 1 k = (case when isnull(file_no,0) + 1 > 6500 then 1
else isnull(file_no,0) + 1 end) ,@id from ex_TBL with (serializable) ORDER by idx desc
위에 @id 는 유저아이디
그리고 with (serializable) 문을 통하여 lock 을 걸었습니다.
그리곤
select top 1 file_no from ex_TBL where id=@id order by idx desc
을 선언하여 유저의 가장최근에 저장된 file_no를 리턴하였습니다.
끝입니다...
저도 까먹을까봐 자세하게 적을려고 했는데
적어보니 너무 단순하고 설명이 약한것 같습니다...ㅡㅡ;
방법을 이곳에 기록합니다.
일단 이슈는...
대략 이렇습니다.
기존에 레코드에 새로운 데이터를 insert 한다.
그리고 그 insert 한 값을 알아낸다...
머 그리 어려운것도 아니네 하겠지만
이번에 제가 해야만 하는 프로그래밍에는 여러가지 제악조건이 있었습니다.
1. 특정 컬럼이 부분 유니크 해야한다.
이말이 먼말이냐하면 예를 들어 file_no 라는 컬럼이 1 부터 6500 까지 중복된 값이 없어야합니다.
insert 할때 file_no 값이 1부터 6500 까지 자동증가해야합니다.
중복된 값이 없어야하고 만일 6500 까지 되었으면 다시 1부터 시작해야합니다.
그러기 위해서는 insert 전에 select 를 하여서 마지막 값을 알아야합니다.
머 그리 어렵지 않게 어떻게 해야하는지 그림이 그려지는 분들도 있을것입니다.
select top 1 file_no from ex_TBL order by idx desc
(idx는 자연증가하는 컬럼)
file_no = file_no +1
if file_no > 6500 then
file_no = 1
end if
insert ex_TBL(file_no) values(file_no)
이런식으로요..
다음 조건을 보시죠...ㅡㅡ;
2.여러사람이 동시에 접속하는경우도 대비해야한다.
한거번에 여러사람이 몰리면
select 문이 실행되서 insert 문이 실행되기전에
또다른 select 문이 실행되어버려서
같은 값을 가질수있게됩니다.
그럼 중복된 값이 inser될수 있겠죠?
lock 를 생각하시는 분이 있으실것입니다.
오케이 일단 넘어가겠습니다.
3.입력된 file_no 가 과연 무엇이 들어갔는지 알아야된다.
사실 file_no는 화일명을 정하는 값이라서 그값을 가지고
서버에 화일을 저장해야합니다.
여러분이 그래야되는것이 아니라 제가 해야할것이 그랬다구요..ㅜ.ㅜ;
머 이것만 때서 생각해보면
다시 select 문을 써서 알아내면 되지 않느냐고 말하시는 분들이 있을겁니다.
이것도 일단 오케이....
자자자 이제 위에 조건들을 모아보면...머리가 아파오기 시작할겁니다.
물론 아니신 고수분들도 있을겁니다...ㅜ.ㅜ;
그럼 제가 이것을 어떻게 처리했는지 기록하겠습니다.
일단 select 문 2개와 insert문 1개가 동시에 처리되어야합니다.
당근 trans 를 생각하시겠죠?
db.begintrans
.
.
.
db.committrans
하지만 이것만으론 잘안되더군요.
어떻게 테스트를 했냐면요.
100번정도 for 문으로 막 돌린 asp 페이지를 여러브라우저에 띄워 한거번에 리플래쉬를 해봤습니다.
쿼리를 던지고 받는 시간을 줄이기위하여 sp 를 사용하였습니다.
중복되는 비율은 적어졌지만 여전히 중복데이타가 나오는 현상이 있었습니다.
이번에는 select 문 1개와 insert 문 1개 그리고 비교구분 1개를 하나의 쿼리로 만들었습니다.
(위에 1.번을 참조)
insert into ex_TBL(file_no,id) select top 1 k = (case when isnull(file_no,0) + 1 > 6500 then 1
else isnull(file_no,0) + 1 end) ,@id from ex_TBL with (serializable) ORDER by idx desc
위에 @id 는 유저아이디
그리고 with (serializable) 문을 통하여 lock 을 걸었습니다.
그리곤
select top 1 file_no from ex_TBL where id=@id order by idx desc
을 선언하여 유저의 가장최근에 저장된 file_no를 리턴하였습니다.
끝입니다...
저도 까먹을까봐 자세하게 적을려고 했는데
적어보니 너무 단순하고 설명이 약한것 같습니다...ㅡㅡ;
fatal error C1853: '' is not a precompiled header file created with this compiler
라는 에러가 뜨면서 잘되던 컴파일이 잘안되는 경우가 있습니다.
블로그나 게시판등을 돌아다녀 보면
pch는 pre-compile 화일입니다.
VC에서는 컴파일 시간을 단축하기 위해서, 처음에 컴파일을 하면서 프리컴파일 화일을 만들어 놓습니다.
소스를 몇군데 수정해도, 변동되지 않은 소스의 부분은 다시 컴파일 하지 않고 프리컴파일된 화일을 이용해
서 링크를 시도하죠.
VC의 버젼을 바꾸면서 이전의 프리컴파일 화일들이 호환이 되지 않아서 일어나는 오류입니다.
단순히 Clear & Rebuild All 하세요
출처 :
http://www.devpia.com/forum/BoardView.aspx?no=141082&forumname=vc_qa
혹은
세팅을 바꾸라는 글들이 있습니다.
http://blog.naver.com/wjdrn82?Redirect=Log&logNo=110007269249
하지만 이래도 안되는 수가 있습니다.
정말 눈물나죠...
그럴땐 과감히...
여태것 제가 글을 올린것들을 보시면 알겠지만 대부분 맨땅에 해딩하기입니다.
혹시 잘못되더라도 저에게 머라하지 마세요....ㅜ.ㅜ;
바로 해당 .pch 화일을 삭제하는 것입니다.
그리고 새로 컴파일을 하거나
clean & rebuild all 을 하시면 됩니다.
꾸벅...
라는 에러가 뜨면서 잘되던 컴파일이 잘안되는 경우가 있습니다.
블로그나 게시판등을 돌아다녀 보면
pch는 pre-compile 화일입니다.
VC에서는 컴파일 시간을 단축하기 위해서, 처음에 컴파일을 하면서 프리컴파일 화일을 만들어 놓습니다.
소스를 몇군데 수정해도, 변동되지 않은 소스의 부분은 다시 컴파일 하지 않고 프리컴파일된 화일을 이용해
서 링크를 시도하죠.
VC의 버젼을 바꾸면서 이전의 프리컴파일 화일들이 호환이 되지 않아서 일어나는 오류입니다.
단순히 Clear & Rebuild All 하세요
출처 :
http://www.devpia.com/forum/BoardView.aspx?no=141082&forumname=vc_qa
혹은
세팅을 바꾸라는 글들이 있습니다.
http://blog.naver.com/wjdrn82?Redirect=Log&logNo=110007269249
하지만 이래도 안되는 수가 있습니다.
정말 눈물나죠...
그럴땐 과감히...
여태것 제가 글을 올린것들을 보시면 알겠지만 대부분 맨땅에 해딩하기입니다.
혹시 잘못되더라도 저에게 머라하지 마세요....ㅜ.ㅜ;
바로 해당 .pch 화일을 삭제하는 것입니다.
그리고 새로 컴파일을 하거나
clean & rebuild all 을 하시면 됩니다.
꾸벅...
img_TBL 테이블에 인덱스 선언이 되어있지 않은 num 이라는 컬럼의 최대값을
알고 싶을때 아래와 같은 두가지 경우를 생각할수 있습니다.
(물론 더많을수 있겠지만 제가 아는 한도내에서...)
select top 1 num from img_TBL order by num desc
-----------------------------------------------------------------
select max(num) from img_TBL
레코드 갯수는 약 5000개가 있고 num컬럼의 값들은 유니크하지 않습니다.
결과적으로 첫번째 쿼리의 최종비용은 0.175 이고
두번째 쿼리의 최종비용은 0.0176 입니다.
무려 10배 차이가 납니다.
원인은 바로 첫번째 쿼리의 처리를 하기위하여 Sort/TopN Sort 작업의 I/O 비용과 cpu 비용이
0.01과 0.09 정도가 나옵니다.
반면 두번째 쿼리는 MAX 값을 구하기 위하여 거의 비용이 들지 않습니다.(I/O 비용 0, CPU 비용 0.000487)
그러므로 두번째 쿼리를 강추합니다.~!
물론 num 이라는 컬럼이 인덱스화 되어있다면 첫번째 쿼리가 근소한 차이로 더 비용이 좋습니다.
알고 싶을때 아래와 같은 두가지 경우를 생각할수 있습니다.
(물론 더많을수 있겠지만 제가 아는 한도내에서...)
select top 1 num from img_TBL order by num desc
-----------------------------------------------------------------
select max(num) from img_TBL
레코드 갯수는 약 5000개가 있고 num컬럼의 값들은 유니크하지 않습니다.
결과적으로 첫번째 쿼리의 최종비용은 0.175 이고
두번째 쿼리의 최종비용은 0.0176 입니다.
무려 10배 차이가 납니다.
원인은 바로 첫번째 쿼리의 처리를 하기위하여 Sort/TopN Sort 작업의 I/O 비용과 cpu 비용이
0.01과 0.09 정도가 나옵니다.
반면 두번째 쿼리는 MAX 값을 구하기 위하여 거의 비용이 들지 않습니다.(I/O 비용 0, CPU 비용 0.000487)
그러므로 두번째 쿼리를 강추합니다.~!
물론 num 이라는 컬럼이 인덱스화 되어있다면 첫번째 쿼리가 근소한 차이로 더 비용이 좋습니다.
자바스크립트를 하다보면 ' 나 " 등의 문자를 그대로 표현해야되는 경우가 있다.
예를 들어서 var = "what's up?";
등의 경우가 있는데
어쩔수 없이
var = 'what's up?';
으로 작성해야되는 경우가 있을수 있다.
즉 문자열을 ' 나 " 로 범위를 선언하는데 그안에 같은 문자를 표현해야하는경우
당연히 브라우저는 var = 'what' 까지만 인식하고 s up? 에서 에러가 날것이다.
이럴경우 문장안의 '라는 문자를 ' 로 바꾸면 된다.
" 도 마찮가지로 " 라고 선언하면
var = 'What's up?' 라고 표현되며
' 이나 " 는 단순히 문자열안의 문자로 해석하여서 제대로된 동작을 기대할수 있다.
당연히 페이지에 보여지는 문장은 what's up? 이라고 표현된다.
예를 들어서 var = "what's up?";
등의 경우가 있는데
어쩔수 없이
var = 'what's up?';
으로 작성해야되는 경우가 있을수 있다.
즉 문자열을 ' 나 " 로 범위를 선언하는데 그안에 같은 문자를 표현해야하는경우
당연히 브라우저는 var = 'what' 까지만 인식하고 s up? 에서 에러가 날것이다.
이럴경우 문장안의 '라는 문자를 ' 로 바꾸면 된다.
" 도 마찮가지로 " 라고 선언하면
var = 'What's up?' 라고 표현되며
' 이나 " 는 단순히 문자열안의 문자로 해석하여서 제대로된 동작을 기대할수 있다.
당연히 페이지에 보여지는 문장은 what's up? 이라고 표현된다.
웹프로그래밍이나 일반 프로그래밍에서
db 트랜잭션을 통하여(BeginTrans, rollBackTrans, commitTrans 등)
만일 에러가 생기면 롤백을 하고 아니면 커밋을 하는 프로그래밍을 하고자 합니다.
이때 분명 트랙잭션 프로그래밍을 했는데 에러메시지를 나타내며 트랙젝션이 되지
않는 경우가 99%입니다.
on Error resume next
문제는 이것을 맨처음에 넣어주어야됩니다.
db에러가 나면 당연히 에러상태가되고 트랜잭션이고 머고 없습니다.
위와 같은 코드를 넣어주면 에러가 나도 에러상태를 유지하면서 다음 단계로
주욱 실행해 나가게 되고 최종단에서 rollBackTrans 를 실행하게 됩니다.
간단한 예제 코드입니다.
on Error resume next
set adoCn=server.CreateObject("ADODB.Connection")
adoCn.open strConnect
adoCn.BeginTrans
adoCn.Execute strSQL
if adoCn.errors.count>0 then
adoCn.rollBackTrans
else
adoCn.commitTrans
end if
set adoCn=nothing
만일 위에 것이 안된다고 하면
If db.Errors.Count <> 0 Then 을
If Err.number <> 0 then 이것으로 바꿔보세요.
아래는 참조입니다.
분산 트랙잭션 오류입니다.(0x8004D00A)
db 트랜잭션을 통하여(BeginTrans, rollBackTrans, commitTrans 등)
만일 에러가 생기면 롤백을 하고 아니면 커밋을 하는 프로그래밍을 하고자 합니다.
이때 분명 트랙잭션 프로그래밍을 했는데 에러메시지를 나타내며 트랙젝션이 되지
않는 경우가 99%입니다.
on Error resume next
문제는 이것을 맨처음에 넣어주어야됩니다.
db에러가 나면 당연히 에러상태가되고 트랜잭션이고 머고 없습니다.
위와 같은 코드를 넣어주면 에러가 나도 에러상태를 유지하면서 다음 단계로
주욱 실행해 나가게 되고 최종단에서 rollBackTrans 를 실행하게 됩니다.
간단한 예제 코드입니다.
on Error resume next
set adoCn=server.CreateObject("ADODB.Connection")
adoCn.open strConnect
adoCn.BeginTrans
adoCn.Execute strSQL
if adoCn.errors.count>0 then
adoCn.rollBackTrans
else
adoCn.commitTrans
end if
set adoCn=nothing
만일 위에 것이 안된다고 하면
If db.Errors.Count <> 0 Then 을
If Err.number <> 0 then 이것으로 바꿔보세요.
아래는 참조입니다.
분산 트랙잭션 오류입니다.(0x8004D00A)
일단 클래스의 속성중에 Instancing 속성을 5 - MultiUse 로 변경하고
프로젝트 속성에서 스레딩 모델 을 아파트 스레드 로 변경해야합니다.
서버 개체 error 'ASP 0178 : 80070005'
Server.CreateObject 액세스 오류
/contents/ta001/ta001Main.asp, line 10
사용 권한을 확인하는 동안Server.CreateObject 호출이 실패했습니다. 이 개체를 액세스할 수 없습니다
이경우에는 Instancing 속성을 변경하지 않은경우이고
'(null)'의 개체를 만드는데 예외 C0000005이(가) 생겼습니다
서버 개체 error 'ASP 0177 : c0000005'
Server.CreateObject 실패
D:CLEVERISLANDSUBSCRIPTION../INCLUDEs/subp_sub_process.asp, line 536
c0000005
이라는 에러가 생겼을 경우 서버에 VB 가 깔려있지 않는경우입니다.
그렇다고 구지 서버에 VB를 깔필요는 없고
패키지 마법사에서 설치화일로 만들어서
서버에서 설치를 하게되면 필요한 비베관련 DLL을 원만큼 깔아줍니다.
정확히 좋은 방법인지는 솔찍히 모르겠지만(오히려 가장최선의 방법일수도 있고...)
이게 나름데로 제일 간단한 방법입니다.
프로젝트 속성에서 스레딩 모델 을 아파트 스레드 로 변경해야합니다.
서버 개체 error 'ASP 0178 : 80070005'
Server.CreateObject 액세스 오류
/contents/ta001/ta001Main.asp, line 10
사용 권한을 확인하는 동안Server.CreateObject 호출이 실패했습니다. 이 개체를 액세스할 수 없습니다
이경우에는 Instancing 속성을 변경하지 않은경우이고
'(null)'의 개체를 만드는데 예외 C0000005이(가) 생겼습니다
서버 개체 error 'ASP 0177 : c0000005'
Server.CreateObject 실패
D:CLEVERISLANDSUBSCRIPTION../INCLUDEs/subp_sub_process.asp, line 536
c0000005
이라는 에러가 생겼을 경우 서버에 VB 가 깔려있지 않는경우입니다.
그렇다고 구지 서버에 VB를 깔필요는 없고
패키지 마법사에서 설치화일로 만들어서
서버에서 설치를 하게되면 필요한 비베관련 DLL을 원만큼 깔아줍니다.
정확히 좋은 방법인지는 솔찍히 모르겠지만(오히려 가장최선의 방법일수도 있고...)
이게 나름데로 제일 간단한 방법입니다.