2011년 12월 29일 목요일
[JavaScript] undefined 값 확인하기
xxx == "undefined"
잘 사용한 예
document.getElementById("xxx").value = xxx == undefined ? "0" : xxx
[아데설구] 스토리14 - 트랜잭션관리의 실무적용
2011년 12월 28일 수요일
톰캣 에러... 해결 할 것
s
INFO: Character decoding failed. Parameter [orderDt] with value [<=order_dt%>] h
as been ignored. Note that the name and value quoted here may be corrupted due t
o the failed decoding. Use debug level logging to see the original, non-corrupte
d values.
java.io.CharConversionException: EOF
at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:80)
at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:46)
at org.apache.tomcat.util.http.Parameters.urlDecode(Parameters.java:410)
at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.j
ava:370)
at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.j
ava:420)
at org.apache.tomcat.util.http.Parameters.handleQueryParameters(Paramete
rs.java:186)
at org.apache.catalina.connector.Request.parseParameters(Request.java:25
94)
at org.apache.catalina.connector.Request.getParameterNames(Request.java:
1148)
at org.apache.catalina.connector.RequestFacade.getParameterNames(Request
Facade.java:371)
at wdf.control.BaseController.getParameterValues(BaseController.java:347
)
at com.wj.ariba.common.control.ProductSubController.getSubProductCodeLis
t(ProductSubController.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at wdf.servlets.FCHttpServlet.invokeRequest(FCHttpServlet.java:312)
at wdf.servlets.FCHttpServlet.processRequest(FCHttpServlet.java:542)
at wdf.servlets.FCHttpServlet.doGet(FCHttpServlet.java:402)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:290)
===================================================================
dataUrl="/common/getSubProductCodeList.do?orderNo=&goodsCd=&orderDt=<%=order_dt%>"
여기서 <=order_dt%> %가 누락되어서 발생되는 문제였음
2011년 11월 20일 일요일
[JAVA] 스트링 배열선언
예를들어
- (잘못된 예)
s = {"aaa","aab","aac"};
- (옳은 사용방법)
2011년 11월 19일 토요일
[android] SimpleCursorAdapter 사용하기
SimpleCursorAdapter
SimpleCursorAdapter는 커서를 XML 파일에 정의된 TextViews 혹은 ImageViews로 컬럼을 맵핑시키는 쉬운 어댑터이다. 당신은 어떤 컬럼을 원하는지 어떤 뷰에 컬럼을 보여주고 싶은지 명시할 수 있다. 그리고 이러한 뷰의 모습을 정의하는 XML파일은 두가지 형태로 바인딩된다. 첫째로 만약 SimpleCursorAdapter.ViewBinder가 가능하다면, setViewValue(android.view.View, android.database.Cursor, int)가 호출된다. 만약 리턴값이 참이면 바인딩이 실행된다. 만약 리턴값이 거짓이고 바인딩 되는 뷰는 TextView 라면 setViewText(TextView, String)가 호출된다. 만약 리턴 값이 거짓이고 바인딩되는 뷰가 ImageView라면 setViewImage(ImageView, String)이 호출된다. 만약 적절한 바인딩이 발견되지 않으면 IllegalStateException이 던져진다. 만약 이 어댑터가 필터링과 함께 사용되면 예를들어 AutoCompleteTextView와 같은 당신은 SimpleCursorAdapter.CursorToStringConverter와 FilterQueryProvider 인터페이스가 필터링프로세스를 컨트롤한다. 자세한 내용은 convertToString(adnroid.database.Cursor) 그리고 runQueryOnBackgroundThread(CharSequence)에 대해서 내용을 참조할 수 있다.
(원문)
An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. You can specify which columns you want, which views you want to display the columns, and the XML file that defines the appearance of these views. Binding occurs in two phases. First, if a SimpleCursorAdapter.ViewBinder
is available, setViewValue(android.view.View, android.database.Cursor, int)
is invoked. If the returned value is true, binding has occured. If the returned value is false and the view to bind is a TextView, setViewText(TextView, String)
is invoked. If the returned value is false and the view to bind is an ImageView,setViewImage(ImageView, String)
is invoked. If no appropriate binding can be found, an IllegalStateException
is thrown. If this adapter is used with filtering, for instance in an AutoCompleteTextView
, you can use the SimpleCursorAdapter.CursorToStringConverter
and the FilterQueryProvider
interfaces to get control over the filtering process. You can refer to convertToString(android.database.Cursor)
andrunQueryOnBackgroundThread(CharSequence)
for more information.
2011년 11월 3일 목요일
[JAVA] ResultSet의 결과수에 따라 로직을 만들려고 할때...
conn = DBHandler.getConnection()
pstmt = conn.prepareStatement(Query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = pstmt.executeQuery();
rs.last();
int vFetchedRow = rs.getRow();
rs.beforeFirst();
이후 다시
while(rs.next){
/// codes
}
해도 에러가 나지 않는다.
[JAVA] ResultSet의 getFetchSize(int)에 대해
1회당 fetch 되는 건수를 나타낸다.
API를 보면 setFetchSize를 이용해서 이 숫자를 변경 할 수도 있다.
만약 ResultSet에 총 몇개의 데이터가 리턴되었는지를 보려면
rs.last()
int row_cnt = rs.getRow();
하면된다.
2011년 11월 2일 수요일
[Oracle] 튜닝보고서
> 사용자가 많지 않은데 오라클+톰캣이 느린경우. 특별한 쿼리나 스크립트가 돌지 않은 상황이다.
* 힌트
> i/o 사용량을 확인하는 쿼리로 확인 결과 엄청난(?) 양의 쿼리가 필요없이 DB에서 돌고 있다.
> 쿼리
select xx.*
from
(select
a.ACTION action_a
,a.ACTION_HASH action_hash_a
,a.ADDRESS
,a.BUFFER_GETS
,a.CHILD_LATCH
,a.COMMAND_TYPE
,a.CPU_TIME
,a.DISK_READS
,a.ELAPSED_TIME
,a.EXECUTIONS
,a.FETCHES
,a.FIRST_LOAD_TIME
,a.HASH_VALUE
,a.INVALIDATIONS
,a.IS_OBSOLETE
,a.KEPT_VERSIONS
,a.LOADED_VERSIONS
,a.LOADS
,a.MODULE MODULE_a
,a.MODULE_HASH MODULE_HASH_a
,a.OPEN_VERSIONS
,a.OPTIMIZER_MODE
,a.PARSE_CALLS
,a.PARSING_SCHEMA_ID
,a.PARSING_USER_ID
,a.PERSISTENT_MEM
,a.ROWS_PROCESSED
,a.RUNTIME_MEM
,a.SERIALIZABLE_ABORTS
,a.SHARABLE_MEM
,a.SORTS
,a.SQL_TEXT
,a.USERS_EXECUTING
,a.USERS_OPENING
,a.VERSION_COUNT
,b.ACTION
,b.ACTION_HASH
,b.AUDSID
,b.CLIENT_IDENTIFIER
,b.CLIENT_INFO
,b.COMMAND
,b.CURRENT_QUEUE_DURATION
,b.FAILED_OVER
,b.FAILOVER_METHOD
,b.FAILOVER_TYPE
,b.FIXED_TABLE_SEQUENCE
,b.LAST_CALL_ET
,b.LOCKWAIT
,b.LOGON_TIME
,b.MACHINE
,b.MODULE
,b.MODULE_HASH
,b.OSUSER
,b.OWNERID
,b.PADDR
,b.PDDL_STATUS
,b.PDML_ENABLED
,b.PDML_STATUS
,b.PQ_STATUS
,b.PREV_HASH_VALUE
,b.PREV_SQL_ADDR
,b.PROCESS
,b.PROGRAM
,b.RESOURCE_CONSUMER_GROUP
,b.ROW_WAIT_BLOCK#
,b.ROW_WAIT_FILE#
,b.ROW_WAIT_OBJ#
,b.ROW_WAIT_ROW#
,b.SADDR
,b.SCHEMA#
,b.SCHEMANAME
,b.SERIAL#
,b.SERVER
,b.SID
,b.SQL_ADDRESS
,b.SQL_HASH_VALUE
,b.STATUS
,b.TADDR
,b.TERMINAL
,b.TYPE
,b.USER#
,b.USERNAME
from v$sqlarea A,
v$session B
where A.disk_reads > 10000
and A.ADDRESS = B.SQL_ADDRESS(+)
AND A.HASH_VALUE = B. SQL_HASH_VALUE(+)
order by A.disk_reads desc) xx
where rownum < 30
* 해결방법
> 모든 jsp 에서 참조하고 있는 의미없는 쿼리를 로그인 시 1회 로드하여 세션에 저장하도록 변경
* 현재 값과 튜닝 후 예상 값(결과)
>
2011년 11월 1일 화요일
[Oracle] 오라클 메모리(1)
* share pool, database buffer cache, redo log buffer, java pool, large pool 이 있는 시스템 영역
PGA - program global area
* 한 프로세스 혹은 쓰레드를 위해 개별적으로 할당되는 공간
* pga 확인 쿼리 - select * from v$process
UGA - user global area
* 전용서버모드 dedicated server 에서만 존재하며 shared server 모드에서는 PGA = UGA 이다.
[Oracle] DB 모니터링 쿼리
- 쿼리가 optimize 가 제대로 되지 않아서 SQL cache 안에서 쉽게 사라지지 않는 쿼리를 확인 하는 쿼리 (1)
SELECT Disk_Reads DiskReads, Executions, SQL_Text SQLText
FROM
(
SELECT Disk_Reads, Executions, LTRIM(SQL_Text) SQL_Text,
Operation, Options,
Row_Number() OVER
(Partition By sql_text ORDER BY Disk_Reads * Executions DESC)
KeepHighSQL
FROM
(
SELECT Avg(Disk_Reads) OVER (Partition By sql_text) Disk_Reads,
Max(Executions) OVER (Partition By sql_text) Executions,
sql_text, p.operation,p.options
FROM v$sql t, v$sql_plan p
WHERE t.hash_value=p.hash_value AND p.operation='TABLE ACCESS'
AND p.options='FULL' AND p.object_owner NOT IN ('SYS','SYSTEM')
AND t.Executions > 1
)
ORDER BY DISK_READS * EXECUTIONS DESC
)
WHERE KeepHighSQL = 1
AND rownum <=30;
- 쿼리가 optimize 가 제대로 되지 않아서 SQL cache 안에서 쉽게 사라지지 않는 쿼리를 확인 하는 쿼리 (2)
(SELECT
sql_text,
child_number,
disk_reads,
executions,
first_load_time,
last_load_time
FROM v$sql
ORDER BY elapsed_time DESC)
WHERE ROWNUM < 10;
- 특정 DISK_READS 횟수 이상만큼의 쿼리를 보는 쿼리 - 문제가 되었던 getsesseioninfo.jsp 는 141484750 회 읽혔음 OTL
SELECT parsing_user_id, executions, sorts, command_type, disk_reads,
sql_text
FROM v$sqlarea
WHERE disk_reads > &&access_level
ORDER BY disk_reads desc;
- V$SQL_WORKAREA_ACTIVE, V$SQL_WORKAREA, V$SQL 뷰를 이용하여 현재 시스템에서 할당된 실행 영역 중 top 10을 찾습니다.
FROM ( SELECT *
FROM ( SELECT workarea_address, actual_mem_used wasize
FROM v$sql_workarea_active
ORDER BY actual_mem_used desc)
WHERE ROWNUM <= 10 ) top_ten,
v$sql_workarea w, v$sql c
WHERE w.workarea_address = top_ten.workarea_address
AND c.address = w.address
AND c.child_number = w.child_number
AND c.hash_value = w.hash_value;
- V$SQL_WORKAREA 뷰를 통해서 다음과 같이 SQL 실행 메모리를 가장 많이 필요로 하는
top 10 실행 영역을 구할 수 있다.
FROM ( SELECT workarea_address, operation_type, policy, estimated_optimal_size
FROM v$sql_workarea
ORDER BY estimated_optimal_size DESC )
WHERE ROWNUM <= 10;
- 커서가 열린 뒤 닫히지 않아서 메모리가 반환되지 못하는 경우
- current cursor 가 몇백 몇천개인지 확인할 것
sum(decode(name,'recursive calls',value)) "Recursive Calls",
sum(decode(name,'opened cursors cumulative',value)) "Opened Cursors",
sum(decode(name,'opened cursors current',value)) "Current Cursors"
FROM v$session ss, v$sesstat se, v$statname sn, v$process p
WHERE se.statistic# = sn.statistic#
AND ( name like '%opened cursors current%'
OR name like '%recursive calls%'
OR name like '%opened cursors cumulative%')
AND se.sid = ss.sid
and ss.paddr=p.addr
AND ss.username is not null
GROUP BY ss.username , se.sid , p.spid
order by "Current Cursors" asc
- 같은 쿼리지만 쉐어할 수 없어서 다른 쿼리로 인식되는 경우 카운트
- PGA/UGA 사용량을 산출하는 쿼리
ttitle '**********< Program Global Area >**********'
ttitle '1. Current pga, uga session memory'
select a.sid, a.username, substr(a.program, 1, 25) as pgm, a.terminal,
max(decode(c.name, 'session pga memory', trunc(value/1000)||'K', 0)) pga,
max(decode(c.name, 'session uga memory', trunc(value/1000)||'K', 0)) uga
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%'
group by a.sid, a.username, substr(a.program, 1, 25), a.terminal;
ttitle '2. Sum of current pga, uga session memory'
select 'Current PGA, UGA session memory SUM:' as sum,
sum(decode(c.name, 'session pga memory', trunc(value/1000),0))||'K' pga_sum,
sum(decode(c.name, 'session uga memory', trunc(value/1000),0))||'K' uga_sum
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%';
ttitle '3. Max(peak) pga, pga session memory'
select a.sid, a.username, substr(a.program, 1, 25) as pgm, a.terminal,
max(decode(c.name, 'session pga memory max', trunc(value/1000)||'K', 0)) pga_max,
max(decode(c.name, 'session uga memory max', trunc(value/1000)||'K', 0)) uga_max
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%'
group by a.sid, a.username, substr(a.program, 1, 25), a.terminal;
ttitle '4. Sum of max(peak) pga, uga session memory'
select 'Max(peak) PGA, UGA session memory SUM:' as sum,
sum(decode(c.name, 'session pga memory max', trunc(value/1000), 0))||'K' pga_m_sum,
sum(decode(c.name, 'session uga memory max', trunc(value/1000), 0))||'K' uga_m_sum
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%';
- i/o 사용량이 많은 순서대로 프로세스를 확인하는 쿼리
B.sid, B.serial#
from v$sqlarea A,
v$session B
where A.disk_reads > 10000
and A.ADDRESS = B.SQL_ADDRESS(+)
AND A.HASH_VALUE = B. SQL_HASH_VALUE(+)
order by A.disk_reads desc;
- 메모리 사용량이 많은 순서대로 프로세스 확인(자세한 확인이 필요함...)
D.sid "SID",
D.username "Oracle User",
D.program "Program",
D.module "Module",
D.status "Status",
D.type "Type",
D.server "Connection",
to_char(D.logon_time,'YYYY-MM-DD HH24:MI:SS') LOGON_TIME,
D.osuser OS_USER ,
decode(D.lockwait,null,'','Blocking') LLOCK,
decode(D.taddr,null,'','TX') TRAN,
A.User_Name,
D.machine MACHINE,
B.Disk_Reads,
B.Buffer_Gets,
B.Rows_Processed,
C.SQL_Text,
A.Address
From V$Open_Cursor A,
V$SQLArea B,
V$SQLText C,
sys.v_$session D
Where 1=1
AND B.ADDRESS = D.SQL_ADDRESS
AND B.HASH_VALUE = D.SQL_HASH_VALUE
And A.Address = C.Address
;
- UGA/PGA 확인 쿼리
- 사용량이 peak 일때 돌려보자
SELECT
s.sid sid
, lpad(s.username,12) oracle_username
, lpad(s.osuser,9) os_username
, s.program session_program
, lpad(s.machine,8) session_machine
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session pga memory') session_pga_memory
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session pga memory max') session_pga_memory_max
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session uga memory') session_uga_memory
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session uga memory max') session_uga_memory_max
FROM
v$session s
ORDER BY session_pga_memory DESC
2011년 10월 30일 일요일
[android] Notepad 예제 중 XML 레이아웃
아래글은
http://developer.android.com/resources/tutorials/notepad/notepad-ex1.html 중
Step 4를 제 기준대로 번역/설명한 내용임
<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android="http://schemas.android.com/apk/res/android"
layout_width="wrap_content"
layout_height="wrap_content">
<listview id="@android:id/list"
layout_width="wrap_content"
layout_height="wrap_content">
<textview id="@android:id/empty"
layout_width="wrap_content"
layout_height="wrap_content"
text="@string/no_notes">
</textview>
</listview>
</linearlayout>
- The ListView and TextView can be thought as two alternative views, only one of which will be displayed at once. ListView will be used when there are notes to be shown, while the TextView (which has a default value of "No Notes Yet!" defined as a string resource in res/values/strings.xml) will be displayed if there aren't any notes to display.
- (번역) ListView와 TextView는 서로 보완대치된다고 생각하면 된다. 오직 한개의 뷰만 화면에 보여질 뿐이다. ListView는 노트의 값이 있을때 보여지게 되고 만약 한개의 값도 존재하지 않으면 TextView(res/values/strings.xml 파일안에 디폴트 값이 'No Notes Yet'으로 설정되어있음)가 보여지게된다.
- The list and empty IDs are provided for us by the Android platform, so, we must prefix the id with android: (e.g., @android:id/list).
- (번역) 리스트와 empty ID들은 안드로이드 플랫폼에 의해 자동으로 제공된다. 그러므로 우리는 반드시 android와 함께 id를 선언해야한다.(예 @android:id/list)
- The View with the empty id is used automatically when the ListAdapter has no data for the ListView. The ListAdapter knows to look for this name by default. Alternatively, you could change the default empty view by using setEmptyView(View) on the ListView.
- (번역) empty id가 선언된 뷰는 ListAdapter에 데이터가 없을때 자동으로 사용된다. ListAdapter는 자동으로 찾기 위해 기본적으로 이 이름을 알고 있다.참고로 default empty view는 ListView에서 setEmptyView(View)를 설정함으로 변경할 수 있다
- More broadly, the android.R class is a set of predefined resources provided for you by the platform, while your project's R class is the set of resources your project has defined. Resources found in the android.R resource class can be used in the XML files by using the android: name space prefix (as we see here).
- (번역) 흔히 android.R 클래스는 플랫폼에서 기본적으로 제공하는 리소스들을 선언하는 클래스이다. 당신의 프로젝트에서 사용되어지는 R class는 프로젝트에서 정의하는 리소스들의 집합체이다. R 클래스 안에서 보여지는 리소스들은 XML파일 안에서 android:name space prefix(이곳에 보여지는대로) 형태로 정의해서 사용될 수 있다.
2011년 10월 20일 목요일
[JAVA] 인코딩에 관하여
UTF8로 설정방법
1. 자바파일 자체의 인코딩
> 이클립스 property - resource - text file encoding
2. 톰캣 구동 시 인코딩
> 환경 설정에서 JAVA_TOOL_OPTIONS 을 다음 파라미터로 추가한다. -Dfile.encoding=UTF8
> 구동/셧다운 시 Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 이 보이면 성공
3. 서블릿에서 request/response 시 인코딩 세팅
> request.setCharacterEncoding("UTF-8");
4. JSP 파일에서 인코딩 선언
> <%@ page contentType="text/html;charset=xxx"%>
> 확인방법 ; <%= System.getProperty("file.encoding") %>
2011년 10월 15일 토요일
2011년 10월 6일 목요일
[jQuery] each loop
$("input[name='chk_item']").each( function (idx){
$(this).eq(idx).val()
});
2011년 9월 29일 목요일
2011년 9월 28일 수요일
[Python] String manipulation
>>> len(s)
2. Concatenate
>>> 'string1234' + 'string5678'
3. Casting to other type
>>> int("42")
4. Casting from other type to string
>>> x = 123
>>> str(x)
2011년 9월 23일 금요일
2011년 9월 21일 수요일
[jQuery] Select box
- visibility
--show
$("#obj_name").css("visibility","visible");
--hide
$("#obj_name").css("visibility","hidden"); - event listener for change
$("#select_lvl10").change(function(){
-- blahblah});
2011년 9월 7일 수요일
2011년 9월 4일 일요일
[python] 파이썬은 들여쓰기가 중요하다.
예를들어
sample1 try: xxxx이것과
sample2 try: xxxx
샘플1과 샘플2는 엄연히 다른 코드로 인식한다.
물론 샘플1과 같이 작성해야한다.
2011년 8월 30일 화요일
[android] log
System.out.println("");
보다는
Log.v();
Log.d();
Log.e();
를 사용하기를 추천한다.
먼저 상단에 아래와 같이 선언해주고
private static final String TAG = "MyActivity";
프로그램에서 직접 아래와 같이 사용한다.
Log.v(TAG, "index=" + i);
자세한 내용은 아래 링크...
http://developer.android.com/reference/android/util/Log.html
2011년 8월 24일 수요일
[JAVA] 현재의 인코딩을 출력
String enc = new java.io.OutputStreamWriter(System.out).getEncoding();
logger.info("default encoding >> " + enc);
2011년 8월 10일 수요일
[Oracle] How to use Orakill
-- spid 확인방법
SELECT spid, osuser, s.program, schemaname
FROM gv$process p, gv$session s
WHERE p.addr = s.paddr;
-- 인스턴스 확인방법
SELECT instance_name
FROM gv$instance;
죽인 뒨에 반드시
select * from V$ACCESS
where object like 'PKG%';
로 확인해 보자
실제 실행명령어
>orakill || 인스턴스이름 || pslice에 보이는 16진수 PID를 변환한 값
16진수를 10진수로 변환하는 사이트
http://easycalculation.com/hex-converter.php
quickslice link. Very handy!!!!!
http://www.idevelopment.info/data/Oracle/DBA_tips/Microsoft_Windows/WINDOWS_1.shtml
[Oracle] Who is locking what???
select * from (
SELECT s.schemaname, p.username, s.sid, p.pid, p.spid, s.username ora,
DECODE(l2.type, 'TX','TRANSACTION ROW-LEVEL', 'TS','TEMPORARY SEGMENT ', 'TD','TABLE LOCK',
'TM','ROW LOCK', l2.type ) vlock,
DECODE(l2.type, 'TX','DML LOCK', 'TS','TEMPORARY SEGMENT', 'TD',DECODE(l2.lmode+l2.request,
4,'PARSE ' || u.name || '.' || o.name, 6,'DDL', l2.lmode+l2.request), 'TM','DML ' || u.name ||
'.' || o.name, l2.type ) type,
DECODE(l2.lmode+l2.request, 2,'RS', 3 ,'RX', 4 ,'S', 5 ,'SRX', 6 ,'X', l2.lmode+l2.request ) lmode ,
DECODE(l2.request, 0,NULL, 'WAIT') wait
FROM v$process p, v$_lock l1, v$lock l2, v$resource r, sys.obj$ o, sys.user$ u, v$session s
WHERE s.paddr = p.addr
AND s.saddr = l1.saddr
AND l1.raddr = r.addr
AND l2.addr = l1.laddr
AND l2.type <> 'MR'
AND l2.type <> 'RT'
AND r.id1 = o.obj# (+)
AND o.owner# = u.user# (+)
)
[Oracle] V$ACCESS view
예를들면 트랜잭션이 없는 상태에서 V$ACCESS를 조회했을때와
A 유저가 DDL 실행 뒤 커밋하지 않은 상태에서 B유저가 DDL을 실행하면
V$ACCESS에 LOCK이 걸린 오브젝트가 조회된다.
2011년 8월 9일 화요일
2011년 6월 29일 수요일
2011년 5월 30일 월요일
oracle Postinstallation Configuration Tasks on Windows
http://download.oracle.com/docs/cd/B28359_01/win.111/b32010/config.htm#BHCHFBIF
2011년 5월 19일 목요일
2011년 5월 6일 금요일
[android] Add a new activity
2011년 5월 3일 화요일
Database link
CONNECT TO user id
identified by password
USING '[ tnsname ]';
* connect to current 옵션은 LDAP 에러를 낼 수 있음
* USING 뒤에오는 TNS 이름은 서버안에 있는 TNSNAME 안에 이름과 동일해야함
* 아이디 패스워드는 쿼테이션이 없어야 함
* TNSNAME은 쿼테이션이 있음
2011년 4월 20일 수요일
ajax로 XML 만들때 컨텐트 타입 설정...
PrintWriter out = response.getWriter();
만약
response.setContentType("text/xml;charset=utf-8");
out 아래에 위치하면 태국어를 비롯한 UTF로 인코딩 되지 않아서 에러가 난다.
정말 중요함...
2011년 4월 14일 목요일
안드로이드에서 데이터베이스 다루기
http://www.devx.com/wireless/Article/40842/1954
Creating and Using Databases in Android
안드로이드에서 데이터베이스 생성 및 사용하기
Every application uses data, and Android applications are no exception. Android uses the open-source, stand-alone SQL database, SQLite. Learn how to create and manipulate a SQLite database for your Android app. by Wei-Meng Lee
모든 애플리케이션은 데이터를 사용한다. 안드로이드 애플리케이션 또한 예외는 없다. 안드로이드는 오픈소스, 스탠드얼론 형태의 SQL Database SQLite를 사용한다. 당신의 안드로이드 애플리케이션을 위해서 SQLite 다루는 법을 배워보자. by Wei-Meng Lee
Database support is the lifeline of every application, big or small. Unless your application deals only with simple data, you need a database system to store your structured data. Android uses the SQLite database system, which is an open-source, stand-alone SQL database, widely used by many popular applications. For example, Mozilla Firefox uses SQLite to store configuration data and iPhone also uses SQLite for database storage.
데이터베이스 지원은 그것이 작던 크던간에 모든 애플리케이션의 생명선이다. 당신이 개발한 애플리케이션이 단순한 데이터만을 다루지 않는다면 구조화된 데이터를 적재할 수 있는 데이터베이스가 필요하다. 안드로이드는 오픈소스, 스탠드얼론이면서 다른 유명한 애플리케이션에의해 널리 사용되는 SQLite 데이터베이스를 사용한다. 예를들면 모질라 파이어폭스는 설정파일을 SQLite에 저장하며 아이폰 또한 데이터베이스 적재목적으로 SQLite를 사용한다.
In Android, the database that you create for an application is only accessible to itself; other applications will not be able to access it. Once created, the SQLite database is stored in the/data/data/e>/databases folder of an Android device. In this article, you will learn how to create and use a SQLite database in Android
안드로이드에서 생성된 데이터베이스는 오직 해당 애플리케이션만 접근이 가능하다. 다른 애플리케이션은 접근이 불가능하다. 일단 생성이 되면 안드로이드 디바이스의 다음 위치에 '패키지이름'으로 저장이된다. /data/data/<패키지이름>/databases . 이 글에서는 안드로이드에서 어떻게 SQLite 데이터베이스를 생성하고 사용하는지 배우게 될 것이다.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQLite Database
Create an Android project using Eclipse and name it Database (see Figure 1).
이클립스를 사용하여 안드로드 프로젝트 생성하고 데이터베이스 이름짓기 (Figure1 참조)

Figure 1. Database: Your new Android project, created using Eclipse.
Creating the DBAdapter Helper Class
Figure 1. 데이터베이스: 이클립스를 사용하여 생성된 신규 안드로이드 프로젝트
DBAdapter Helper 클래스를 생성하자
A good practice for dealing with databases is to create a helper class to encapsulate all the complexities of accessing the database so that it's transparent to the calling code. So, create a helper class called DBAdapter that creates, opens, closes, and uses a SQLite database.
데이터베이스를 다루는 좋은 방법으로는 데이터베이스에 접근하는 모든 복잡한 요소들을 캡슐화해서 언제든지 불러서 사용할 수 있도록 해주는 헬퍼 클래스를 생성하는 것이다.
First, add a DBAdapter.java file to the src/
먼저
In the DBAdapter.java file, import all the various namespaces that you will need:
DBAdapter.java 파일에서 필요한 모든 클래스를 임포트하자.
(주: 임포트를 해야만 해당클래스 내의 메쏘드를 사용 할 수 있죠)
=========================================================
package net.learn2develop.Databases;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter
{
}
=========================================================
Next, create a database named bookstitles with the fields shown in Figure 2.
다음으로 Figure2에 나온대로 bookstitles라는 데이터베이스를 생성하자

Figure 2. The Database Fields: This shows the titles table you will be building in this article.
Figure2. 데이터베이스 필드 : 이 글에서 생성할 테이블을 보여준다.
In the DBAdapter.java file, define the following constants shown in Listing 1.
DBAdapter.java 파일에서 리스트1과 같이 상수들을 정의한다.
===================================================
package net.learn2develop.Database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter
{
public static final String KEY_ROWID = "_id";
public static final String KEY_ISBN = "isbn";
public static final String KEY_TITLE = "title";
public static final String KEY_PUBLISHER = "publisher";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "books";
private static final String DATABASE_TABLE = "titles";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "isbn text not null, title text not null, "
+ "publisher text not null);";
private final Context context;
}
===================================================
The DATABASE_CREATE constant contains the SQL statement for creating the titles table within the books database.
DATABASE_CREATE 상수에는 books 데이터베이스 내에 titles 테이블을 만들기 위한 SQL 문장이 포함되어있다.
Within the DBAdapter class, you extend the SQLiteOpenHelper class-an Android helper class for database creation and versioning management. In particular, you override the onCreate() and onUpgrade() methods (as shown in Listing 2).
DBAdapter 클래스 내에는 데이터베이스 생성 및 버전 관리를 할 수 있는 SQLiteOpenHelper 클래스를 상속받고 특히 onCreate() 그리고 onUpgrade() 를 오버라이드 한다.
The onCreate() method creates a new database if the required database is not present. The onUpgrade() method is called when the database needs to be upgraded. This is achieved by checking the value defined in the DATABASE_VERSION constant. For this implementation of the onUpgrade() method, you will simply drop the table and create the table again.
onCreate() 메써드는 애플리케이션에서 필요하지만 현재는 존재하지 않는 새로운 데이터베이스를 생성한다. onUpgrade() 메써드는 데이터베이스가 업그레이드가 필요할때 호출된다.(주:업데이트는 인서트,삭제,업데이트를 의미함) DATABASE_VERSION 에 정의되어 있는 상수를 체크함으로 가능하다. onUpgrade() 메써드를 사용함으로 테이블을 드랍하고 새롭게 생성할 수 있다.
You can now define the various methods for opening and closing the database, as well as the methods for adding/editing/deleting rows in the table (see Listing 3).
이제 데이터베이스를 열고 닫기 위한 다양한 메써드를 정의할 수 있고 테이블 내의 열을 추가/편집/삭제할 수 있는 메써드 또한 정의가 가능하다.
===================================================
public class DBAdapter
{
//...
//...
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a title into the database---
public long insertTitle(String isbn, String title, String publisher)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_ISBN, isbn);
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_PUBLISHER, publisher);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular title---
public boolean deleteTitle(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---retrieves all the titles---
public Cursor getAllTitles()
{
return db.query(DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER},
null,
null,
null,
null,
null);
}
//---retrieves a particular title---
public Cursor getTitle(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER
},
KEY_ROWID + "=" + rowId,
null,
null,
null,
null,
null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a title---
public boolean updateTitle(long rowId, String isbn,
String title, String publisher)
{
ContentValues args = new ContentValues();
args.put(KEY_ISBN, isbn);
args.put(KEY_TITLE, title);
args.put(KEY_PUBLISHER, publisher);
return db.update(DATABASE_TABLE, args,
KEY_ROWID + "=" + rowId, null) > 0;
}
}
===================================================
Notice that Android uses the Cursor class as a return value for queries. Think of the Cursor as a pointer to the result set from a database query. Using Cursor allows Android to more efficiently manage rows and columns as and when needed. You use a ContentValues object to store key/value pairs. Its put() method allows you to insert keys with values of different data types.
여기서 눈여겨 봐야 할 것은 안드로이드는 커서 클래스를 쿼리에 대한 리턴값으로 사용한다는 것이다. 커서를 데이터베이스 질의에 대한 결과 값이라고 생각하는 것이다. 커서는 안드로이드가 열과 컬럼을 필요로 할때 효율적으로 사용할 수 있도록 도와준다. 또한 ContentValues 오브젝트에 키/값의 짝으로 데이터를 저장할 수 있다. 해당 오브젝트에서 put() 메써드를 사용해서 키와 다른 데이터 타입의 값을 삽입할 수 있다.
The full source listing of DBAdapter.java is shown in Listing 4.
DBAdapter.java 의 풀 소스를 리스트4에서 볼 수 있다.
=============================================
package net.learn2develop.Database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter
{
public static final String KEY_ROWID = "_id";
public static final String KEY_ISBN = "isbn";
public static final String KEY_TITLE = "title";
public static final String KEY_PUBLISHER = "publisher";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "books";
private static final String DATABASE_TABLE = "titles";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "isbn text not null, title text not null, "
+ "publisher text not null);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion
+ " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS titles");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a title into the database---
public long insertTitle(String isbn, String title, String publisher)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_ISBN, isbn);
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_PUBLISHER, publisher);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular title---
public boolean deleteTitle(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID +
"=" + rowId, null) > 0;
}
//---retrieves all the titles---
public Cursor getAllTitles()
{
return db.query(DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER},
null,
null,
null,
null,
null);
}
//---retrieves a particular title---
public Cursor getTitle(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER
},
KEY_ROWID + "=" + rowId,
null,
null,
null,
null,
null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a title---
public boolean updateTitle(long rowId, String isbn,
String title, String publisher)
{
ContentValues args = new ContentValues();
args.put(KEY_ISBN, isbn);
args.put(KEY_TITLE, title);
args.put(KEY_PUBLISHER, publisher);
return db.update(DATABASE_TABLE, args,
KEY_ROWID + "=" + rowId, null) > 0;
}
}
=============================================
Using the Database
데이터베이스 사용하기
You are now ready to use the database along with the helper class you've created. In the DatabaseActivity.java file, create an instance of the DBAdapter class:
이제 직접 작성한 helper 클래스를 따라서 데이터베이스를 사용할 준비가 되었다. DatabaseActivity.java 파일에서 DBAdapter 클래스의 인스턴스를 생성해 보자
=====================================================
package net.learn2develop.Database;
import android.app.Activity;
import android.os.Bundle;
public class DatabaseActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
}
}
=====================================================
Adding a Title
타이틀 추가하기
To add a title into the titles table, use the insertTitle() method of the DBAdapter class:
타이틀 테이블에 타이틀을 추가하기 위해서는(새로운 열을 추가하기 위해서는) DBAdapter의 insertTitle() 메써드를 사용한다.
=====================================================
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
//---add 2 titles---
db.open();
long id;
id = db.insertTitle(
"0470285818",
"C# 2008 Programmer's Reference",
"Wrox");
id = db.insertTitle(
"047017661X",
"Professional Windows Vista Gadgets Programming",
"Wrox");
db.close();
}
=====================================================
The insertTitle() method returns the ID of the inserted row. If an error occurs during the adding, it returns -1.
If you examine the file system of the Android device/emulator, you can observe that the books database is created under the databases folder (see Figure 3).
insertTitle() 메써드는 추가된 열의 ID를 리턴한다. 만약 추가 중에 에러가 발생한다면 -1을 리턴하게 된다.
만약 안드로이드 디바이스/에뮬레이터를 사용하는 경우 데이터베이스 폴더 아래에 books 데이터베이스가 제대로 생성되어 있는지 확인이 필요하다.

Figure 3. The Database Folder: The books database is created in the databases folder.
Figure 3. 데이터베이스 폴더: books 데이터베이스는 데이터베이스 폴더에 위치하고 있다.
Retrieving All the Titles
모든 테이블 가져오기
To retrieve all the titles in the titles table, use the DBAdapter class' getAllTitles() method (see Listing 5).
The result is returned as a Cursor object. To display all the titles, you first need to call the Cursor object's moveToFirst() method. If it succeeds (which means there is at least one row available), display the details of the title using the DisplayTitle() method (defined below). To move to the next title, call the Cursor object's moveToNext() method:
타이틀 테이블의 모든 타이틀을 가져오기 위해서는 DBAdapter 의 getAllTitles() 메써드를 사용해야한다.(리스트 5 참조) 결과는 커서 객체로 리턴된다. 모든 타이틀을 보여주기 위해서는 반드시 커서 객체의 moveToFirst() 메써드를 호출해야 한다. 만약 성공한다면 (이 말은 적어도 한 개 이상의 열이 존재한다는 말이다) DisplayTitle() 메써드를 사용해서 타이틀의 세부를 보여준다. 다음 타이틀로 이동하기 위해서는 moveToNext()를 호출해서 사용한다.
=====================================================
public void DisplayTitle(Cursor c)
{
Toast.makeText(this,
"id: " + c.getString(0) + "\n" +
"ISBN: " + c.getString(1) + "\n" +
"TITLE: " + c.getString(2) + "\n" +
"PUBLISHER: " + c.getString(3),
Toast.LENGTH_LONG).show();
}
=====================================================

Figure 4 shows the Toast class displaying one of the titles retrieved from the database.
FIgure 4는 Toast 클래스가 데이터베이스로 부터 가져온 하나의 타이틀을 가져와 보여주고 있다.
Retrieving a Single Title
하나의 타이틀 가져와서 보여주기
To retrieve a single title using its ID, call the getTitle() method of the DBAdapter class with the ID of the title:
ID를 사용해서 하나의 타이틀을 가져오려면 DBAdapter 클래스에서 타이틀의 ID를 사용해서 getTitle() 메써드를 호출한다.
=====================================================
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
//---get a title---
db.open();
Cursor c = db.getTitle(2);
if (c.moveToFirst())
DisplayTitle(c);
else
Toast.makeText(this, "No title found",
Toast.LENGTH_LONG).show();
db.close();
}
=====================================================
The result is returned as a Cursor object. If a row is returned, display the details of the title using the DisplayTitle() method, else display an error message using the Toast class.
결과는 커서 객체로 리턴된다. 만약 결과가 리턴된다면 DisplayTitle() 메써드를 사용해서 타이틀의 상세를 표시하고 그렇지 않으면 토스트 클래스를 사용해서 에러를 표시한다.
Updating a Title
타이틀 업데이트하기
To update a particular title, call DBAdapter's updateTitle() method by passing the ID of the title you want to update as well as the values of the new fields (Listing 6).
특정한 타이틀을 업데이트하기 위해서는 DBAdapter 클래스의 updateTitle() 메써드를 타이틀의 ID와 업데이트 하기위한 값을 파라미터로 호출한다.
A message is displayed to indicate if the update is successful. At the same time, you retrieve the title that you have just updated to verify that the update is indeed correct.
만약 업데이트가 성공하였으면 메시지가 표시되고 동시에 방금 업데이트 된 값을 가져와서 제대로 반영 되었음을 보여준다.
Deleting a Title
타이틀의 삭제
To delete a title, use the deleteTitle() method in the DBAdapter class by passing the ID of the title you want to delete:
타이틀을 삭제하기 위해서 DBAdapter 클래스에서 deleteTitle() 메써드를 지우고자 하는 ID를 파라미터로 호출한다.
=====================================================
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
//---delete a title---
db.open();
if (db.deleteTitle(1))
Toast.makeText(this, "Delete successful.",
Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Delete failed.",
Toast.LENGTH_LONG).show();
db.close();
}
=====================================================
A message is displayed to indicate if the deletion is successful.
만약 삭제가 성공했다면 성공을 알리는 메시지가 표시된다.
Upgrading the Database
데이터베이스 업그레이드
To upgrade the database, change the DATABASE_VERSION constant in the DBAdapter class to a value higher than the previous one. For example, if its previous value was 1, change it to 2:
데이터베이스를 업그레이드하기 위해서 DBAdapter 클래스의 DATABASE_VERSION 상수를 과거버전보다 높은 숫자로 변경한다.예를들면 지난 값이 1이었다면 2로 변경한다.

Figure 5. The LogCat Window: The message shows that the database has been upgraded.
Figure 5. 로크 캣 윈도 : 데이터베이스가 업그레이드 되어음을 보여주는 메시지
=====================================================
public class DBAdapter
{
public static final String KEY_ROWID = "_id";
public static final String KEY_ISBN = "isbn";
public static final String KEY_TITLE = "title";
public static final String KEY_PUBLISHER = "publisher";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "books";
private static final String DATABASE_TABLE = "titles";
//---change this to a higher value---
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "isbn text not null, title text not null, "
+ "publisher text not null);";
=====================================================
When you run the application one more time, you will see the message in Eclipse's LogCat window (see Figure 5) indicating that the database has been upgraded.
애플리케이션을 1회이상 실행할때 이클립스의 로그캣 윈도에서 데이터베이스가 업그레이드 되었음을 알리는 메시지를 볼수 있을 것이다.
Easy Database Access
손 쉬운 데이터베이스 접근
Using the DBAdapter class pattern defined in this article, you can easily access database records for your own Android applications. One important thing to note is that all SQLite databases created in Android are visible only to the application that created it. If you need to share common data, you need to use a content provider, a topic that will be covered in a future article.
DBAdapter 클래스를 사용하는 패턴이 이 글에서 정의 되었다. 이제 개발하고있는 안드로이드 애플리케이션에서 데이터베이스 접근이 용이해 졌을 것이다. 한가지 더 중요한 것은 안드로이드 안에서 SQLite 데이터베이스는 오로지 데이터베이스를생성한 애플리케이션에게만 보여진다. 만약 공유하고자 하는 데이터가 있다면 Content Provider를 사용해야한다. 이에 대한 내용은 다음글에서 다뤄질 예정이다.
Wei-Meng Lee is a Microsoft MVP and founder of Developer Learning Solutions, a technology company specializing in hands-on training on the latest Microsoft technologies. He is an established developer and trainer specializing in .NET and wireless technologies. Wei-Meng speaks regularly at international conferences and has authored and coauthored numerous books on .NET, XML, and wireless technologies. He writes extensively on topics ranging from .NET to Mac OS X. He is also the author of the .NET Compact Framework Pocket Guide, ASP.NET 2.0: A Developer's Notebook (both from O'Reilly Media, Inc.), and Programming Sudoku (Apress). Here is Wei-Meng's blog.