데이터베이스 2017. 6. 30. 08:00


Function Based Index 또는 Descending Index로 인덱스 생성 시 Dictionary 테이블(ALL_IND_COLUMNS)의 인덱스 컬럼이 SYS_로 시작하는 알 수 없는 컬럼으로 조회가 됩니다.  또는 ALL_TAB_COLS 테이블에는 생성하지 않는 컬럼(SYS_로 시작하는)이 조회됩니다. 테이블 정의서 작성을 위해 위의 Dictionary 테이블을 사용할 때 주의하세요!



Descending Index 생성 및 Dictionary 테이블 조회


1. 테스트 테이블 생성 및 Descending Index 생성


1
2
3
4
5
6
7
8
9
10
/* 테이블 생성 */
CREATE TABLE TB_IND_TEST(
COL1            VARCHAR2(10),
COL2            VARCHAR2(20),
COL3            VARCHAR2(30) GENERATED ALWAYS AS ( COL1 || COL2 ) VIRTUAL
);
 
/* Descending Index 생성 */
CREATE INDEX IDX_TB_IND_TEST_01 
ON TB_IND_TEST (COL1 DESC, COL2 DESC);
cs


ALL_TAB_COLS 테이블의 HIDDEN_COLUMN항목과 VIRTUAL_COLUMN의 차이를 알기 위해 테이블을 생성 시 COL3 컬럼을 가상컬럼으로 생성하였습니다.


가상컬럼 SYNTAX

COLUMN_NAME [DATA_TYPE] [GENERATED ALWAYS] AS ( expression ) [VIRTUAL]


2. Dictionary 테이블 조회


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* 인덱스 컬럼 조회 */
SELECT T.INDEX_NAME
     , T.TABLE_NAME
     , T.COLUMN_NAME
  FROM ALL_IND_COLUMNS T
 WHERE 1=1
   AND T.TABLE_NAME = 'TB_IND_TEST'
;
 
/* ALL_TAB_COLUMNS 테이블 조회 */
SELECT T.TABLE_NAME
     , T.COLUMN_NAME
     , T.DATA_TYPE
  FROM ALL_TAB_COLUMNS T
 WHERE 1=1
   AND T.TABLE_NAME = 'TB_IND_TEST'
 ORDER BY T.COLUMN_ID
;
 
/* ALL_TAB_COLS 테이블 조회 */
SELECT T.TABLE_NAME
     , T.COLUMN_NAME
     , T.DATA_TYPE
     , T.HIDDEN_COLUMN
     , T.VIRTUAL_COLUMN
  FROM ALL_TAB_COLS T
 WHERE 1=1
   AND T.TABLE_NAME = 'TB_IND_TEST'
 ORDER BY T.COLUMN_ID
;
cs


- ALL_TAB_COLS 조회 결과



ALL_TAB_COLUMNS 테이블에서는 조회되는 않는 SYS_로 시작되는 컬럼이 조회가 되었습니다. Descending Index의 가상컬럼이자 히든컬럼으로 생성되었습니다.

그리고 가상컬럼으로 생성한 COL3 컬럼은 가상컬럼이지만, HIDDEN COLUMN은 아닙니다.


'데이터베이스' 카테고리의 다른 글

오라클 권한 조회  (0) 2017.06.28
오라클 계정과 권한  (0) 2017.06.23
오라클 TABLESPACE와 DATAFILE  (0) 2017.06.16
TIMESTAMP 연산  (0) 2017.05.11
오라클 - PIVOT과 UNPIVOT  (0) 2017.02.02
posted by 생각퍼즐
:
데이터베이스 2017. 6. 28. 08:00


사용자 및 ROLE에 부여된 권한조회하기



데이터베이스 작업 시 "권한이 불충분합니다."라는 오류 메시지와 마주할 때가 있습니다. 그럴때는 당황하지 마시고 현재 사용자의 권한을 확인하여 처리하시면 됩니다.


사용자 생성


권한부여 및 조회를 위한 테스트 계정을 만들어보겠습니다.


- SYNTAX

CREATE USER USER_NAME IDENTIFIED BY PASSWORD

[ DEFAULT TABLESPACE TABLESPACE_NAME ]

[ TEMPORARY TABLESPACE TEMP ]

;


- EX)

CREATE USER TEST IDENTIFIED BY TEST1234

DEFAULT TABLESPACE USERS

TEMPORARY TABLESPACE TEMP;


※ 사용자 삭제

- SYNTAX

DROP USER USER_NAME [CASCADE];


- EX)

DROP USER TEST_USER CASCADE;


- CASCADE : 사용자에게 부여된 권한이나 사용자가 만든 객체가 존재할 경우 CASCADE 옵션을 사용해야 해당 사용자를 삭제할 수 있음



데이터베이스 접속 테스트


사용자가 정상적으로 생성되었는지 데이터베이스에 접속을 시도하면

아래와 같은 오류가 발생됩니다.


sqlplus TEST_USER/TEST1234@ORCL


ERROR: ORA-01045: user TEST_USER lacks CREATE SESSION privilege; logon denied


사용자에게 접속권한이 없다고 ERROR 메시지를 던져주네요!



권한부여

sqlplus / as sysdba

SQL> GRANT CREATE SESSION, CREATE TABLE TO TEST_USER;


-접속확인

SQL> conn TEST_USER/TEST1234@ORCL


※ 사용자에게 권한 부여 및 회수와 관련된 자세한 내용은 오라클 계정과 권한 포스팅을 참고하세요!



권한조회


1. USER 또는 ROLE에 부여된 시스템 권한조회


SELECT GRANTEE, PRIVILEGE, ADMIN_OPTION

 FROM DBA_SYS_PRIVS;

또는

SELECT USERNAME, PRIVILEGE, ADMIN_OPTION

 FROM USER_SYS_PRIVS;


- GRANTEE : 시스템 권한을 부여받은 USER 또는 ROLE

- USERNAME : 현재 접속된 사용자

- PRIVILEGE : 부여받은 시스템 권한

- ADMIN_OPTION : 부여받은 시스템 권한을 다른 사용자에게 부여할 수 있음(YES일 경우)


2. USER 또는 ROLE에 부여된 객체 권한조회


SELECT GRANTEE, OWNER, TABLE_NAME, PRIVILEGE, GRANTOR

 FROM DBA_TAB_PRIVS

또는

SELECT GRANTEE, OWNER, TABLE_NAME, PRIVILEGE, GRANTOR

 FROM USER_TAB_PRIVS


- GRANTEE : 객체 권한을 부여받은 USER 또는 ROLE

- OWNER : 객체의 소유자

- TABLE_NAME : 객체

- GRANTOR : 객체 권한을 부여해준 USER


3. USER 또는 ROLE에 부여된 ROLE 조회


SELECT *
 FROM DBA_ROLE_PRIVS
또는
SELECT *
 FROM USER_ROLE_PRIVS

- GRANTED_ROLE : 부여된 ROLE
- DEFAULT_ROLE : DEFAULT_ROLE 여부


※ DEFAULT ROLE

   - 데이터베이스 설치 시 자동으로 생성되는 ROLE

   - 대표적인 Default Role은 CONNECT, RESOURCE가 있음

   - RESOURCE 롤은 UNLIMITED_TABLESPACE라는 권한이 할당되어 있음

   - UNLIMITED_TABLESPACE 권한을 가진 사용자는 데이터베이스에 존재하는 모든 테이블      스페이스를 저장공간으로 사용가능 

'데이터베이스' 카테고리의 다른 글

오라클 Hidden Column - SYS_로 시작하는 컬럼  (1) 2017.06.30
오라클 계정과 권한  (0) 2017.06.23
오라클 TABLESPACE와 DATAFILE  (0) 2017.06.16
TIMESTAMP 연산  (0) 2017.05.11
오라클 - PIVOT과 UNPIVOT  (0) 2017.02.02
posted by 생각퍼즐
:
데이터베이스 2017. 6. 23. 14:10


SYS와 SYSTEM 계정


1. SYS 계정

  • 오라클 데이터베이스가 설치되면 자동으로 생성되는 계정(슈퍼 사용자)
  • Dictionary Table의 소유자
  • SYS 스키마에는 테이블 생성 불가(데이터베이스에 의해서만 수정가능)
  • sysdba로 접속할 때 기본 스키마
  • 데이터베이스 생성가능(sysdba privilege를 가짐)


2. SYSTEM

  • SYS계정과 마찬가지로 데이터베이스가 설치되면서 생성되는 계정
  • Dictionary View 소유자
  • 데이터베이스 생성 불가
  • 데이터베이스 관리에 필요한 table 및 view 생성


권한
  • 시스템 권한 : 데이터베이스 접속, 사용자 및 오브젝트 생성 등
  • 오브젝트 권한 : 오브젝트 사용에 대한 권한

1. 시스템 권한


시스템 권한 (CREATE, ALTER, DROP)

설명 

 CREATE USER

 사용자 생성 권한 

 CREATE SESSION

 데이터베이스 접속 권한 

 CREATE ANY TABLE

 모든 사용자의 테이블 생성 권한 

 SELECT ANY TABLE

 모든 사용자의 테이블 조회 권한 

 CREATE TABLE

 테이블 생성 권한 

 CREATE VIEW

 뷰 생성 권한 

 CREATE PROCEDURE

 프로시저 생성 권한 

 CREATE SEQUENCE

 시퀀스 생성 권한 

 SYSDBA

 데이터베이스 관리를 위한 슈퍼권한

 SYSOPER 데이터베이스 관리 권한



1.1 SYSDBA와 SYSOPER의 상세권한


권한 

 설명

 SYSOPER

  • 데이터베이스 수정(open, mount, backup 등)
  • 데이터베이스 인스턴스 시작/종료
  • 파라미터 파일 생성
  • 테이블스페이스 및 컨트롤파일 백업
  • 데이터베이스 아카이브/노아카이브 로그 모드 전환
  • 데이터베이스 완전 복구
  • 접속세션 제한
※ 다른 유저의 데이터를 조회할 수는 없음

 SYSDBA
  • SYSOPER 권한
  • 데이터베이스 생성 및 삭제 
  • 데이터베이스 불완전 복구


SQL PLUS를 이용해서 SYSDBA로 접속하기

=> sqlplus / as sysdba

=> show user 명령어 결과는 SYS로 나옵니다.

위의 SYS계정에서 설명했듯이 SYSDBA 접속 기본 스키마이기 때문입니다.



1.2 시스템 권한 부여 및 회수 문법


1.2.1 권한 부여


GRANT [권한/ROLE] TO [USER/ROLE/PUBLIC]

[WITH ADMIN OPTION]


- PUBLIC : 시스템 권한 및 ROLE을 모든 사용자에게 부여

- WITH ADMIN OPTION : 부여받은 권한을 다른 사용자 및 ROLE에게 부여

※ WITH ADMIN OPTION을 사용하여 부여한 권한은 연쇄적으로 회수되지 않음 


EX) GRANT CREATE TABLE, CREATE USER TO SCOTT WITH ADMIN OPTION;



1.2.2. 권한 회수


REVOKE [권한/ROLE] FROM [USER/ROLE/PUBLIC]

 

EX) REVOKE CREATE TABLE, CREATE USER FROM SCOTT;



2. 오브젝트 권한


오브젝트 소유자는 해당 오브젝트의 모은 권한을 가지며, 오브젝트에 대한 특정 권한을 다른 사용자에게 부여할 수 있습니다.


권한

TABLE

 VIEW

 PROCEDURE

 SEQUENCE

 SELECT

O

 

 INSERT

O

 

 

 

 DELETE

O

 

 

 ALTER

O

 

 

 INDEX

O

 

 

 

 EXECUTE


 

 O

 


2.1 오브젝트 권한 부여 및 회수 문법


2.1.1 권한 부여


GRANT 권한[COLUMN] ON OBJECT TO [USER/ROLE/PUBLIC]

[WITH GRANT OPTION]


- WITH GRANT OPTION : 부여받은 권한을 다른 사용자 및 ROLE에게 부여

※ WITH GRANT OPTION을 사용하여 부여한 권한은 연쇄적으로 회수됨 


EX) GRANT INSERT ON TB_TEST TO SCOTT WITH ADMIN OPTION;



2.1.2 권한 회수


REVOKE [권한/ALL] ON OBJECT FROM [USER/ROLE/PUBLIC]

[CASCADE CONSTRAINTS]


- 객체권한의 회수는 부여한 사용자만이 할 수 있음

- CASCADE CONSTRAINTS : 참조 객체에 사용된 참조 무결성 제약을 함께 삭제할 수 있음

 

EX) REVOKE INSERT ON TB_TEST FROM SCOTT;


'데이터베이스' 카테고리의 다른 글

오라클 Hidden Column - SYS_로 시작하는 컬럼  (1) 2017.06.30
오라클 권한 조회  (0) 2017.06.28
오라클 TABLESPACE와 DATAFILE  (0) 2017.06.16
TIMESTAMP 연산  (0) 2017.05.11
오라클 - PIVOT과 UNPIVOT  (0) 2017.02.02
posted by 생각퍼즐
:
데이터베이스 2017. 6. 16. 15:44

TABLESPACE와 DATAFILE


- TABLESPACE : 논리적 데이터 저장 공간

- DATAFILE     : 물리적 데이터 저장 공간, 즉 실제 데이터가 저장되는 Disk영역을 말 함



TABLESPACE 생성 Script


 - DATAFILE 1개

1
2
3
CREATE TABLESPACE TABLESPACE_NAME
DATAFILE 'D:\ORACLE\ORADATA\ORCL\TEST_TS01' SIZE 100M
AUTOEXTEND ON NEXT 2M MAXSIZE 500M;
cs


 - DATAFILE 1개 이상

1
2
3
DATAFILE 'D:\ORACLE\ORADATA\ORCL\TEST_TS01' SIZE 30G AUTOEXTEND OFF
       , 'D:\ORACLE\ORADATA\ORCL\TEST_TS02' SIZE 30G AUTOEXTEND OFF
       , 'D:\ORACLE\ORADATA\ORCL\TEST_TS03' SIZE 30G AUTOEXTEND OFF
cs


AUTOEXTEND

- DATAFILE SIZE 자동확장 여부, ON/OFF로 설정

- AUTOEXTEND가 OFF로 설정할 경우, NEXT, MAXSIZE의 크기는 0으로 설정해야 한다.

  NEXT, MAXSIZE를 기술하지 않으면 Default 값(0)으로 설정됨


NEXT

- 초기설정 값(100M)보다 많은 공간이 요구될때 자동으로 확장되는 디스크 공간크기

- K(킬로 바이트), M(메가 바이트)단위 사용


MAXSIZE

 - 확장 될수 있는 최대 크기 입니다.

 - K(킬로 바이트), M(메가 바이트)단위 사용

 - MAXSIZE가 명시되지 않았으면 데이터 파일의 최대 크기는 디스크 공간과 OS에서 지원되는 최대 파일 크기로 제한 된다. 


ex) Windows 32bit : 16G

    Windows 64bit : 32G




TABLESPACE 수정 Script


1
2
3
4
5
6
7
8
9
10
1) TABLEPACE에 수동으로 DATAFILE 추가
ALTER TABLESPACE DQ_MAN_TS ADD DATAFILE 'D:\ORACLE\ORADATA\ORCL\DQ_MAN_TS02.DBF' SIZE 30G;
 
2) 기존 DATAFILE 속성 변경 -  수동으로 SIZE증가
ALTER DATABASE DATAFILE 'D:\ORACLE\ORADATA\ORCL\DQ_MAN_TS01.DBF' resize 2G;
 
3) 기존 DATAFILE 속성 변경 -  자동으로 SIZE증가
  ALTER DATABASE DATAFILE 'D:\ORACLE\ORADATA\ORCL\DQ_MAN_TS01.DBF'
  AUTOEXTEND ON NEXT 5M
  MAXSIZE 30G;
cs




TABLESPACE 용량 및 사용량 확인


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT A.TABLESPACE_NAME AS "테이블스페이스"
     , ROUND(SUM(A.TOTAL)/1024/1024,1"전체(MB)"
     , ROUND(SUM(A.TOTAL)/1024/1024,1)-ROUND(SUM(A.FREE_SPACE)/1024/1024,1"사용(MB)"
     , ROUND(SUM(A.FREE_SPACE)/1024/1024,1"여유(MB)"
     , ROUND((ROUND(SUM(A.TOTAL)/1024/1024,1)- ROUND(SUM(A.FREE_SPACE)/1024/1024,1))/ROUND(SUM(A.TOTAL)/1024/1024,1)*100,2"사용률(%)"
  FROM (SELECT TABLESPACE_NAME
             , 0 AS TOTAL
             , SUM(BYTES) AS FREE_SPACE
          FROM DBA_FREE_SPACE
         GROUP BY TABLESPACE_NAME
        UNION
        SELECT TABLESPACE_NAME
             , SUM(BYTES) TOTAL
             , 0 AS FREE_SPACE
          FROM DBA_DATA_FILES
         GROUP BY TABLESPACE_NAME) A
 GROUP BY A.TABLESPACE_NAME
 ORDER BY TABLESPACE_NAME
;
cs


DBA_SEGMENTS   : 세그먼트의 할당량을 조회

DBA_FREE_SPACE : 사용가능한 익스텐트 정보 조회

DBA_DATA_FILES : 할당된 물리적 공간


'데이터베이스' 카테고리의 다른 글

오라클 권한 조회  (0) 2017.06.28
오라클 계정과 권한  (0) 2017.06.23
TIMESTAMP 연산  (0) 2017.05.11
오라클 - PIVOT과 UNPIVOT  (0) 2017.02.02
오라클의 동적 PL SQL 작성 - EXECUTE IMMEDIATE  (0) 2017.01.24
posted by 생각퍼즐
:
프로그래밍 2017. 5. 22. 00:56



브라우저를 이용해 파일을 다운로드할 경우 인코딩 문제로인해 한글 및 특수문자 깨짐현상이 발생하죠!


이런문제를 해결하기 위해서는 첫 번째 Client가 사용하는 브라우저 확인이 필요합니다. 두 번째 브라우저별 파일명 인코딩 처리가 필요합니다.





1. 파일다운로드를 위한 컨트롤러 소스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RequestMapping(value="/notice/fileDownload")
    public void fileDownload(HttpServletRequest req, HttpServletResponse res, NoticeBean noticeBean) throws Exception{
        
        String fileStrNm = req.getParameter("fileStrNm");
        String fileOrgNm = req.getParameter("fileOrgNm");
        
        byte fileByte[] = FileUtils.readFileToByteArray(new File(path+ "/" +fileStrNm));
         
        String encodedFileName = FileUtil.getEncodedFileName(fileOrgNm, CommonUtil.getBrowser(req));
        res.setContentType("application/octet-stream");
        res.setContentLength(fileByte.length);
        res.setHeader("Content-Disposition""attachment; fileName=\"" +encodedFileName +"\";");
        res.setHeader("Content-Transfer-Encoding""binary");
        res.getOutputStream().write(fileByte);
         
        res.getOutputStream().flush();
        res.getOutputStream().close();
        
    }
cs



2. Client의 브라우저 확인


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static String getBrowser(HttpServletRequest request) {
   String userAgent = request.getuserAgent("User-Agent");
  
   if (userAgent.indexOf("MSIE"> -1 || userAgent.indexOf("Trident"> -1 ){
        //IE 버전 별 체크  >>  Trident/7.0(IE 11), Trident/6.0(IE 10) , Trident/5.0(IE 9) , Trident/4.0(IE 8)
        return "MSIE";
   } else if (userAgent.indexOf("Chrome"> -1) {
        return "Chrome";
   } else if (userAgent.indexOf("Opera"> -1) {
        return "Opera";
   } else if ( userAgent.indexOf("Firefox"> -1 ) {
        return "Firefox";
   }
   return "Safari";
}
cs



3. 브라우저별 파일명 인코딩 처리


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  // 파일 다운로드 시 Cilent의 브라우저에 따라 파일명의 인코딩 설정
    public static String getEncodedFileName(String filename, String browser) throws Exception {
        
           String encodedFilename = null;
           if (browser.equals("MSIE")) {
               // 한글 파일명 깨짐현상을 해결하기 위해 URLEncoder.encode 메소드를 사용하는데,
               // 파일명에 공백이 존재할 경우 URLEncoder.encode 메소드에의해 공백이 '+' 로 변환됩니다.
               // 변환된 '+' 값을 다시 공백으로(%20)으로 replace처리하시면 됩니다.
               // \\+의 의미는 정규표현식에서 역슬래시(\)는 확장문자로
               // 역슬래시 다음에 일반문자가 오면 특수문자로 취급하고 
               // 역슬래시 다음에 특수문자가 오면 그 문자 자체를 의미 
               // 기존 파일명에 있던 '+' 는 URLEncoder.encode() 메소드에 의해 '%2B' 로 변환이 됩니다.
                encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+""%20");
           } else if (browser.equals("Firefox")) {
                encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1"+ "\"";
           } else if (browser.equals("Opera")) {
                encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1"+ "\"";
           } else if (browser.equals("Chrome")) {
              StringBuffer sb = new StringBuffer();
              for (int i = 0; i < filename.length(); i++) {
                          char c = filename.charAt(i);
                          if (c > '~') {
                                     sb.append(URLEncoder.encode("" + c, "UTF-8"));
                          } else {
                                // ASCII문자(0X00 ~ 0X7E)는 URLEncoder.encode를 적용하지 않는다.     
                                  sb.append(c);
                          }
              }
              encodedFilename = sb.toString();
           } else {
              throw new RuntimeException("Not supported browser");
           }
           return encodedFilename;
    }
cs


위와 같이 처리하시면 파일 다운로드 시 파일명이 깨지는 현상을 방지할 수 있습니다.


posted by 생각퍼즐
:
데이터베이스 2017. 5. 11. 18:02



SQL의 실행 시간 측정등 밀리 세컨드 단위의 정밀한 작업이 필요한 곳에 TIMESTAMP 데이터 타입을 사용하죠!



그렇다면, TIMESTAMP 형식으로 등록된 데이터의 비교연산은 어떻게 할까요?



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- TIMESTAMP 연산을 위한 2개의 COLUMN이 포함된 테이블을 생성합니다.
CREATE TABLE TB_TIME_STAMP(
FROM_TIME           TIMESTAMP,
TO_TIME             TIMESTAMP
)
;
 
-- 생성된 테이블에 TIMESTAMP 형식의 데이터를 등록합니다.
INSERT INTO SCOTT.TB_TIME_STAMP(FROM_TIME, TO_TIME)
VALUES(SYSTIMESTAMP - 1/24, SYSTIMESTAMP)
;
 
-- 마직막으로 아래처럼 TIMESTAMP 연산을 수행하여 시간차이를 초단위로 변환합니다.
SELECT EXTRACT(HOUR FROM DT) * 3600 + EXTRACT(MINUTE FROM DT) * 60 + EXTRACT(SECOND FROM DT) AS DIFF_TIME
  FROM (
        SELECT TO_TIME - FROM_TIME AS DT
          FROM SCOTT.TB_TIME_STAMP
       )
;
cs


참고로, 위의 SYSTIMESTAMP - 1/24의 의미는 현재 시간에서 1시간 전의 값을 의미합니다.

그래서 두 컬럼의 연산 결과는 항상 3600.XXX가 되겠죠!

'데이터베이스' 카테고리의 다른 글

오라클 권한 조회  (0) 2017.06.28
오라클 계정과 권한  (0) 2017.06.23
오라클 TABLESPACE와 DATAFILE  (0) 2017.06.16
오라클 - PIVOT과 UNPIVOT  (0) 2017.02.02
오라클의 동적 PL SQL 작성 - EXECUTE IMMEDIATE  (0) 2017.01.24
posted by 생각퍼즐
:
프로젝트 2017. 4. 21. 01:24

제안요청서란?



프로젝트 끝나고 본사로 복귀해서  refresh 좀 하려고 하면 누가 부르죠^^

ㅇㅇ기관 제안요청서가 떴는데... 같이 제안서를 쓰자고ㅜ.ㅜ

이런 불상사를 피하기 위해서는 휴가 일정을 잘 맞춰야 되요^^


공공기간(민간기업 포함)의 프로젝트를 수주하기위해서는 제안서 제출 및 제안발표는 기본적으로 필수 프로세스입니다. 제안서 작성은 오늘 포스팅은 주제인 제안요청서에 기반하여 작성되어 집니다.


본격적으로 제안요청서에 대해 알아보기 전에 이번 포스팅은 공공기관의 전자정부 사업을 중점으로 작성된다는 것을 알려드립니다.



제안요청서(Request for Proposal)가 뭐죠?

- 시스템 구축 및 SW 서비스를 발주하기 위하여 입찰 대상자에게 발주자의 요구사항을 제시하기 위한 문서입니다.


발주의 종류와 발주 프로세스에 대해서 알고 넘어가죠.


1. 전자정부 사업의 발주 종류

 - 분리발주 : 프로젝트의 투명성 확보를 위해 시스템 구축 시 SW 서비스 업무와 HW 도입 사업을 분리하여 발주

- 분할발주 : SW의 전문성 높이기 위해 분석/설계 단계와 구현/테스트 단계를 나누어 발주 


2. 발주 프로세스(ISO-12207)

1) 발주준비 : 비즈니스, HW/SW 요구사항 정의(발주 계획서)

2) 제안요청서 : 제안 요구사항 문서화(RFP, 평가기준서)

3) 계약 : 입찰공고(나라장터 등), 제안평가, 공급자(수행사) 선정, 계약체결(평가 결과서, 계약서)

4) 공급자(수행사) 관리 : 수행계획 검토 및 승인, 계약진행(사업수행계획서)

5) 인수 및 종료 : 검사, 인수 테스트, 인수(종료 보고서)



발주기관에서 제안요청서를 제시하는 이유는 뭘까요?


 관점

설명 

 발주기관

  • 개발 및 운영 시스템의 요구사항(기능적 요구사항, 비기능적 요구사항)을 식별
  • 기술력과 경제성을 고려한 사업자 선정

 제안사

  • 프로젝트의 과업범위를 예측
  • 기능점수(Function Point)를 통한 SW 대가산정

 감사기관

  • 사업추진 타당성 및 대국민 서비스의 효용성을 고려하여 사업의 성과를 객관적으로 평가



그렇다면, 제안요청서가 갖추어야할 요건도 있겠네요!


  1. 사업의 목적 및 이해 : 사업(프로젝트)을 추진하는 이유 및 목적, 과업범위 제시
  2. 제약사항 : Legacy 시스템과 상호운영성을 위한 개발언어, Framework 지정
  3. 기능적 요구사항 : 공통, 핵심, 선택 요구사항 제시, 기능점수를 통한 대가산정
  4. 비기능적 요구사항 : 성능, 보안, UI 등 시스템의 품질요구사항
  5. 관리적 요구사항 : 수시, 정기(주말 및 월간보고), 중간, 완료보고, 인력관리
  6. 입찰조건 : 참여기업 조건 및 이력 등 공시
  7. 제안평가 기준 : 기술 및 가격평가 기준 제시 

위의 제안요청서의 요건 중 기능적 및 비기능적 요구사항에 대해 좀 더 상세하게 알아보죠!

1. 기능적 요구사항

공통 요구사항 

 핵심 요구사항

선택 요구사항 

  • 시스템에서 반복적으로 수행되는 모듈 또는 컴포넌트
  • Login/Logout, 권한관리, 메뉴
  • 연계모듈
  • SW 아키텍처의 주요기능, 기술적 검토가 필요한 새로운 기술 시도
  • 시스템의 주요 업무기능(예: 민원처리 기능 등)
  • IoT, 빅데이터 분석 등
  • 서비스 품질측면에서 수행사가 선택하여 수행가능한 요구사항
  • 제안서에 추가 제시한 제안사항이 있다면 필수 요구사항으로 변경됨


2. 비기능적 요구사항


성능

보안

UI 

  • 성능평가 대상 선정
  • Virtural User 수 선정
  • 평가도구, 결과보고서
  • 개인정보 안전성 확보조치
  • 접속로그 저장 및 관리
  • 웹 표준 준수
  • 웹 호환성을 고려한 화면 설계
  • Device(PC, Mobile 등)에 독립성을 고려한 화면 설계 


3. 비기능적 요구사항 중 성능 요구사항의 사례


 요구사항

시나리오 

목표치 

우선순위 

 Batch처리

(OLAP)

당일에 발생한 트랜잭션 데이터(거래정보 등)을 추출, 가공, 적재를 22시에 매일 수행

 30분 이내 

 Online 조회

(OLTP)

End User가 웹 브라우저를 통해 조회하는 화면을 대상으로 10 ~ 20개 ROW를 기준

3초 이내 

통계정보 조회 

기간(일별, 월별, 년도별), 부서별 민원처리 통계조회

30초 이내 

하 




제안요청서(RFP)가 뭐고, 왜 작성하는지, 무슨 내용으로 작성되는지에 대해 간단하게 적어봤습니다. 백문이 불여 일견이라고 나라장터 등에서 제안요청서를 한 번 보는게 훨씬 더 도움이 된다고 생각됩니다.

posted by 생각퍼즐
:
프로그래밍 2017. 4. 18. 08:00

페이지 이동 시 검색조건 유지


페이징 처리된 화면에서 페이지(페이지 번호) 이동 시 검색조건을 유지하기 위한 소스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function fn_movePage(pageNo){
    // 검색조건 INPUT ID
    var voArrId = ["searchDiv""searchValue"];
    
    // 검색조건 값
    var voArrValue = ["${noticeBean.searchDiv}","${noticeBean.searchValue}"];
 
    // FORM NAME
    var formNm = "frm";
 
    // URL
    var gotoUrl = "<c:url value='/notice/noticeList.do'/>";
    
    gfn_pagingSearch(pageNo,formNm,gotoUrl,voArrId,voArrValue);
}
 
/*-----------------------------------------------------------------------------------------------
 * function : gfn_pagingSearch(pageNo,formNm,gotoUrl,voId,voValue)
 * 설명    : 페이지 버튼 클릭하면 VO에 담긴 검색조건으로 검색하기 
 * param    : pageNo(페이지번호),formNm(폼이름),gotoUrl(액션url),voArrId 배열,voArrValue 배열
----------------------------------------------------------------------------------------------*/
function gfn_pagingSearch(pageNo,formNm,gotoUrl,voArrId,voArrValue) {
        
    var arr = new Array();
    var i = 0;
    for(var i in voArrId){
        var retVal  = new Object();
        retVal.arrId = voArrId[i];
        retVal.arrValue = voArrValue[i];
        arr[i] = retVal;
        ++i;    
    }
    
    $("#pageIndex").val(pageNo);
    for(var i=0;i<arr.length;i++){
        var retVal = arr[i];
        $("#"+retVal.arrId).val(retVal.arrValue);
    }
    $("#"+formNm).attr("action",gotoUrl).submit();
}
cs

 


posted by 생각퍼즐
:
프로그래밍 2017. 4. 18. 00:22

SSL(TLS) 인증 우회하는 JAVA 코드


여러 공공기관에서 많은 데이터를 개방하고 있죠~


예전에는 엑셀파일 형식으로 많이 개방했었는데, 요즘은 데이터 최신성 유지 및 활용성을 높이기 위해 OPEN API 방식으로 제공을 하고있습니다.


가끔 SSL(TLS)가 적용된 OPEN API 호출 시 인증서 오류(SSL통신)가 발생하기도 합니다. 인증서 만료 또는 인증서 없을 경우 발생하죠!


SSL의 개념에 대해 궁금하시면 여기를 참조하세요!


이러한 문제를 해결하는 방법으로 아래 소스코드처럼 인증우회(인증서 무시)하는 방법이 있습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
        Document xml = null;      
        HttpURLConnection connection = null;
        
        try{
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            
            URL restUrl = new URL(url);
            String protocol = restUrl.getProtocol();
            
            /* 프로토콜이 HTTPS일 경우 서버쪽 인증서를 신뢰할 수 있도록 처리 */
            if(protocol.toLowerCase().equals("https")){
                TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    @SuppressWarnings("unused")
                    public void checkClientTrusted(X509Certificate[] certs,String authType) {
                    }
                    @SuppressWarnings("unused")
                    public void checkServerTrusted(X509Certificate[] certs,String authType) {
                    }
                    @Override
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] arg0,
                            String arg1) throws CertificateException {
                        // TODO Auto-generated method stub
                    }
                    @Override
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] arg0,
                            String arg1) throws CertificateException {
                        // TODO Auto-generated method stub
                    }
                } };
 
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            }
 
            /*connection 정보 설정*/
            connection = (HttpURLConnection) restUrl.openConnection();
            connection.setRequestProperty("Accept""text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            connection.setRequestProperty("Accept-Language""ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
            connection.setRequestProperty("Connection""keep-alive");
            connection.setConnectTimeout(Configure.HTTP_CONN_TIME_OUT);
            if(timeOut > 0){
                connection.setReadTimeout(timeOut);
            }else{
                connection.setReadTimeout(Configure.HTTP_READ_TIME_OUT);
            }
            
            /* 호출한 결과를 XML문서로 저장 */
            xml = documentBuilder.parse(connection.getInputStream());
            
        }catch(MalformedURLException me){
            me.printStackTrace();
            throw new MalformedURLException("MalformedURLException");
        }catch(Exception e){
            throw new Exception(e.getMessage());
        }finally{
            /* resource */
            connection.disconnect();
        }
 
cs



posted by 생각퍼즐
:
아키텍처 2017. 4. 14. 02:14


소프트웨어 아키텍처 평가기법


소프트웨어 또는 시스템을 구축하기 위해 가장 중요한 것이 아키텍처죠!

아키텍처에는 시스템의 특성, 요구사항 등을 해결하기 위한 전략과 제약사항 포함되어야 겠죠.


이번에는 이렇게 힘들게 만든 아키텍처가 잘만든 것인지에 대한 평가를 위한 평가기법에 대해 알아 보겠습니다.



1. 소프트웨어 아키텍처 평가기법의 개요


1) 소프트웨어 아키텍처(Software Architecture) 평가기법이란?

 - 아키텍처의 접근법이 품질속성(보안, 성능, UI 등)에 미치는 영향을 판단하여 아키텍처 적합성을 판단 및 평가하는 표준기법


2) 소프트웨어 아키텍처 평가기법 유형


 관점

유형

내용 및 기법

 가시성

 가시적 평가

 Inspection, Review, Validation & Verification

 비가시적 평가

 SAAM, ATAM, CBAM, ARID, ADR 

 시점

 이른 평가

 아키텍처 구축과정 중 어느 때나 평가 가능

 비용 및 평가부담 적음

 늦은 평가

 기존 시스템의 요구사항에 대한 아키텍처의 적합성을  판단할 때  사용 



2. 평가기법 관계도 및 평가기법 설명


1) 평가기법 관계도




2) 평가기법 설명


 가. ATAM(Architecture Tradeoff Analysis Method)

 - 아키텍처의 품질속성에 초점을 맞춘 평가기법으로 품질속성 간의 상충관계를 평가

 - 특징

   -> 명확한 분석, Legacy System 분석에 활용가능

   -> 비기능적 요구사항(신뢰성, 사용성, 유지보수성 등) 중심분석

   -> 아키텍처 스타일, 품질속성은 SAAM 영향을 받음


 나. CBAM(Cost Benefit Architecture Method)

 - 아키텍처의 경제적 측면에 초점을 맞춘 평가기법

 - 특징

   -> ATTAM의 결과물을 기반으로하여 아키텍처의 경제성을 분석

   -> ROI 측면의 의사결정을 위한 기준 제시


 다. SAAM(Software Architecture Analysis Method)

 - 사용자의 요구사항 시나리오와 아키텍처 간의 매핑을 통한 적합성 분석

 - 특징

   -> 아키텍처의 Modifiability와 Functionality 집중분석

   -> 평가 경험이 없는 조직에서도 활용가능


 라. ADR

 - 아키텍처의 구성요소 간의 응집도를 평가하는 기법


 마. ARID(Architecture Reviews for Intermediate Design)

 - 전체 아키텍처가 아닌 특정 부분에 대한 품질요소에 집중하여 평가

'아키텍처' 카테고리의 다른 글

웹 환경의 이해(2/2)  (0) 2017.01.18
웹 환경의 이해(1/2)  (0) 2017.01.18
posted by 생각퍼즐
: