글쓴이 보관물: totoli78

MS SQLSERVER 저장프로시저에서 OUTPUT, RETURN TABLE 사용

1. 예제 테이블 만들기

테스트를 하기 위해서 테이블과 데이터를 생성한다.

————————————————————————————–

CREATE TABLE [dbo].[제품테이블](
[품번] [int] IDENTITY(1,1) NOT NULL,
[품명] [nvarchar](50) NULL,
[단가] [int] NULL,
CONSTRAINT [PK_titles] PRIMARY KEY CLUSTERED ([품번] ASC)
)

GO

INSERT INTO 제품테이블(품명, 단가) VALUES
(‘AA’, ‘1000’)
, (‘AB’, ‘2000’)
, (‘AC’, ‘3000’)
, (‘AD’, ‘4000’)
, (‘AE’, ‘5000’)
, (‘AF’, ‘6000’)
, (‘AG’, ‘7000’)
, (‘AH’, ‘8000’)
, (‘BA’, ‘1000’)
, (‘BB’, ‘2000’)
, (‘BC’, ‘3000’)
, (‘BD’, ‘4000’)
, (‘CE’, ‘5000’)
, (‘CF’, ‘6000’)
, (‘CG’, ‘7000’)
, (‘CH’, ‘8000’)

GO

————————————————————————————–

 

2. OUTPUT 파라미터와 RETURN 값이 있는 저장프로시저 만들기

————————————————————————————–

CREATE PROC usp_UpdatePrice
@rate  float = 0.01
,@product nvarchar(50)
,@ucount int OUTPUT               — 출력파라미터로 지정

AS
SET NOCOUNT ON

UPDATE 제품테이블

 SET 단가 = 단가 + (단가 * @rate)
WHERE 품명 LIKE @product

SET @ucount = @@ROWCOUNT

IF @@ERROR <> 0

    RETURN(-1)                           — 출력값으로 지정

​ ELSE
BEGIN

​       SELECT TOP 1 * FROM 제품테이블
       WHERE 품명 LIKE @product
ORDER BY 단가 DESC

       RETURN(0)— 출력값으로 지정


END

————————————————————————————–

참고로 RETURN(값) 에서 값에는 정수만 가능하다.

위와 같이 프로시저를 만들고  아래와 같이 프로시저를 호출하여 OUTPUT 파라미터와 RETURN 값을

확인해 보자

————————————————————————————–

DECLARE @cnt int
DECLARE @rtn int

EXEC @rtn = usp_UpdatePrice -0.1, ‘CE’, @cnt OUTPUT

SELECT @cnt AS 업데이트, @rtn AS 오류

————————————————————————————–

위와 같이 구문을 실행하면 아래와 같은 출력 값을 볼 수 있다.

위의 예제에서 처럼 출력되는 것을 확인할 수 있다.

참고로, 테이블 반환 매개변수는 OUTPUT의 매개변수로 사용할 수 없다.

 

3. 프로시저에서 반환하는 쿼리결과 테이블을 테이블변수에 저장하기

 

쿼리 결과로 테이블을 반환하는 프로시저를 먼저 생성한다.

————————————————————————————–

CREATE PROCEDURE TABLERETURN
AS
BEGIN
SELECT * FROM 제품테이블
END


 

1) 테이블변수에 저장하기

위 프로시저에서 출력되는 결과를 테이블 변수에 저장하기

————————————————————————————–

DECLARE @TResults TABLE (
PartID int
,PartName nvarchar(20)
,Price int
)

INSERT @TResults EXEC TABLERETURN

SELECT * FROM @TResults

————————————————————————————–

 

2) 임시테이블에 저장하기

위 프로시저에서 출력되는 결과를 테이블 변수에 저장하기

————————————————————————————–

CREATE TABLE #TResults (
PartID int
,PartName nvarchar(20)
,Price int
)

INSERT #TResults EXEC TABLERETURN

SELECT * FROM #TResults

DROP TABLE #TResults

————————————————————————————–

위 코드를 실행하면 아래와 같이 출력된다.

————————————————————————————–

** 원격 서버의 프로시저를 호출 해 테이블 반환을 받을 때 설정값

 

자바스크립트 예제로 살펴보는 JSONP의 기본원리

JSONP는 한 웹페이지에서 도메인이 다른 웹페이지로 데이터를 요청할 때 사용하는 자바스크립트 개발 방법론입니다.

기본적으로 웹 브라우저는 도메인이 다른 웹 페이지로는 Ajax 등의 방법으로 접근하지 못하게 제한하고 있는데, 이것을 동일출처원칙(Same-origin policy)이라고 합니다. 그러나 실무에서는 부득이 다른 도메인에 연결된 서버로 데이터를 요청해야만 하는 상황을 만나게 됩니다. JSONP는 바로 이러한 경우에 동일출처원칙을 회피하는 일종의 편법 입니다.

JSONP는 동일출처원칙을 회피하기 위해 <script> 요소를 이용합니다. 본래 자바스크립트에서는 Ajax를 비롯한 어떠한 방법으로도 직접 다른 도메인의 웹페이지로 데이터를 요청할 수 없습니다. 그러나 <script> 요소는 도메인이 다른 스크립트 파일이라 하더라도 임베드할 수 있기 때문에, 이 성질을 이용하는 것입니다.

국내 웹에서 JSONP에 대해 검색을 하면, jQuery를 사용하여 간편하게 JSONP를 구현한 방법을 소개하는 포스팅이 주류를 이루고 있습니다. 이 방법은 Ajax를 구현할 때와 유사한 방식으로 쉽고 간편하게 JSONP를 구현할 수 있게 해주지만, 한편으로는 JSONP의 기본원리에 대해서는 소홀하게 만드는 양면성을 가지고 있습니다.

금번 포스팅에서는 JSONP의 기본원리를 설명하기 위하여, 순수 자바스크립트로 JSONP를 구현한 예제코드를 소개합니다. 또한 Ajax와의 비교를 통해 JSONP의 효용과 한계에 대해서 짚어볼 것입니다. 마지막으로 실무에서 활용하기 좋은 jQuery에서의 JSONP 구현방법까지 살펴보고 나면 글을 마치게 될 것입니다.

 

예제코드 개요

회원명부에서 이름으로 검색하는 웹페이지를 작성하려고 합니다. 그런데 한 가지 문제가 있습니다. 메인 웹 서버에는 a.epiloum.net 도메인이 연결되어 있는데 반해, 회원명부 DB는 b.epiloum.net 도메인에 연결된 서버에 있다는 것입니다. 동일출처원칙으로 인하여 일반적인 방법으로는 a.epiloum.net의 웹페이지가 b.epiloum.net에 있는 웹페이지를 호출할 수는 없습니다.

(이러한 상황을 타개하는 가장 간편한 방법은, a.epiloum.net에서 b.epiloum.net의 DB를 접근할 수 있도록 접근권한을 조정하는 것입니다. 하지만 웹 서버와 DB 서버가 여러 대로 분산되어 있는 대형 웹 서비스라면, 이것 또한 녹록치 않을 것입니다.)

위와 같은 상황을 JSONP를 통하여 극복해보도록 하겠습니다. 이 예제는 PHP + MySQL 환경을 기준으로 하며, DB 서버로 사용하는 b.epiloum.net에도 웹 서버가 설치되어 있다고 가정할 것입니다.

 

클라이언트측 예제코드 – http://a.epiloum.net/index.html

아래는 JSONP로 데이터를 요청할 검색화면 웹페이지의 예제코드입니다. 이 소스코드 파일은 a.epiloum.net라는 도메인 아래에 위치할 것입니다.

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
<!DOCTYPE html>
<html lang="ko">
<head>
<title>JSONP Sample Code</title>
<meta charset="utf-8">
<script type="text/javascript">
function find()
{
    var j = document.createElement('script');
    var s = encodeURIComponent(document.getElementById('str').value);
 
    j.setAttribute('src', u);
    j.setAttribute('type', 'text/javascript');
    document.getElementsByTagName('body')[0].appendChild(j);
    return false;
}
function loadList(arr)
{
    var o = document.getElementById('list');
    var l;
 
    while(o.childNodes.length)
    {
        o.removeChild(o.lastChild);
    }
 
    for(var i=0; i<arr.length; i++)
    {
        l = document.createElement('li');
        l.appendChild(document.createTextNode(arr[i]));
        o.appendChild(l);
    }
}
</script>
</head>
<body>
<input id="str" type="text" size="50" />
<input id="btn" type="button" value="입력" onclick="return find()" />
<ul id="list"></ul>
</body>
</html>

실제로 코드를 웹 서버에 올려 접속해보시면, 텍스트 입력란과 버튼이 표시된 화면을 볼 수 있습니다. 텍스트 입력란에 적당한 텍스트를 입력하고 버튼을 누르면, find()라는 자바스크립트 함수가 실행될 것입니다. 이 함수는 새로운 <script> 요소를 생성하여 <body> 요소 아래에 추가하는 역할을 합니다.

여기서 주목할 것은 <script>의 src 속성인데요, URL의 도메인이 현재 도메인과는 다른 b.epiloum.net임을 확인할 수 있습니다. GET 파라메터 또한 확인해두셔야 하는데요. callback이라는 파라메터에는 “loadList”라는 문자열이 들어가 있는데, 이것과 같은 이름을 가진 loadList()라는 함수가 있다는 점을 기억하시기 바랍니다. 이어서 s라는 파라메터에는 사용자가 텍스트 입력란에 타이핑한 값이 들어가게 됩니다.

마지막으로 위 예제코드 어디에서도 호출하는 부분이 없는 loadList() 함수가 있습니다. 이 함수는 인자로 받은 배열의 내용을 <ul id=”list”> 요소 아래에 표시하는 역할을 합니다.

 

서버측 예제코드 – http://b.epiloum.net/find.php

이제 앞서의 예제코드에서 <script> 요소를 생성하여 호출하는 find.php의 소스코드를 살펴볼 차례입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?
// Send HTTP Header
header('Content-Type:application/javascript');
// Connect to DB
$dbi = mysql_connect('localhost', '****', '****');
mysql_select_db('****', $dbi);
mysql_query('SET NAMES utf8', $dbi);
// DB Search
$sql = 'SELECT name FROM member WHERE ';
$sql .= 'name LIKE "%' . mysql_real_escape_string($_GET['s']) . '%"';
$res = mysql_query($sql, $dbi);
$dat = array();
while($v = mysql_fetch_assoc($res))
{
    $dat[] = $v['name'];
}
// Output
echo $_GET['callback'] . '(' . json_encode($dat) . ')';
?>

이 소스코드는 회원명부를 담고 있는 `member` 테이블에서, 이름에 해당하는 `name` 필드에 검색어가 포함된 레코드를 LIKE 문을 사용해 검색합니다. 검색어는 GET 파라메터 s를 통해 입력받습니다. 검색한 결과는 PHP 변수인 $dat에 배열로 담아두게 됩니다. 여기까지는 그다지 특이한 것이 없어보입니다.

주목할 곳은 바로 검색결과를 출력하는 부분에 있습니다. 일반적으로 Ajax를 사용할 때는 검색결과를 JSON 형식으로 출력하고 마치는 것이 보통입니다. 그러나 JSONP 방식을 사용한 위 예제코드는 조금 달라보입니다. 바로 GET 파라메터 callback을 통해 전달받은 이름의 함수를 호출하는 자바스크립트 코드를 출력하고 있는 것이죠. 그리고 그 함수의 인자로, 회원명부에서 검색한 결과를 담은 배열이 들어갑니다.

 

예제코드 실행시의 결과

이제 앞서 살펴본 두 소스코드를 연결해서 생각해보면 JSONP의 전말이 드러납니다. 일단 검색화면 웹페이지에서 “john”을 입력하고 버튼을 클릭하면, 아래와 같은 <script> 요소가 생성되었을 것입니다.

<script src=”http://b.epiloum.net/find.php?callback=loadList&s=john”></script>

이렇게 호출된 find.php 파일은 아래와 같이, callback 파라메터로 전달받은 이름인 loadList() 함수를 실행하는 스크립트를 출력합니다. 함수의 인자로 “john”으로 검색한 결과가 배열이 들어오는 것은 물론입니다.

loadList([“John Miller”,”John C. Potter”])

이렇게 검색화면 웹페이지에서 정의한 loadList() 함수가 실행되면, 처음 우리가 살펴보았던대로 <ul id=”list”> 요소 아래에 John이라는 단어로 검색한 결과가 목록으로 보이게 됩니다.

 

JSONP의 기본원리와 한계

위 예제를 토대로 우리는 이제 JSONP가 작동하는 원리를 아래와 같이 정리할 수 있습니다.

  1. 데이터를 요청할 페이지에, 데이터를 받아 처리할 콜백 함수를 먼저 준비해놓습니다. 그 후에 <script> 요소를 생성하여, 데이터 요청을 합니다.
  2. 데이터 요청을 받은 페이지에서는 콜백 함수를 실행하는 스크립트를 출력합니다. 이 때 callback 함수의 인자에는 요청받은 데이터가 들어가게 됩니다.

Ajax와 JSONP 비교 개념도

Ajax와 JSONP 비교 개념도

우리가 잘 알고 있는 Ajax와 비교해보면 흐름 자체가  크게 다르지 않습니다. 단지 콜백함수를 실행하는 타이밍이 달라졌을 뿐입니다. Ajax는 데이터 만을 일단 responseText 속성으로 가져온 후, XMLHttpRequest 객체에서 onreadystatechange 속성에 담긴 콜백함수를 실행합니다. 반면에 JSONP는 서버측에서 이미 콜백함수를 실행하는 코드를 반환하는 점이 다를 뿐입니다. 이처럼 Ajax와 동일한 효과를 가지면서도 동일출처원칙을 회피할 수 있는 것, 이것이 JSONP가 가진 효용성이라고 할 수 있습니다.

한편 Ajax와 비교하여 JSONP가 가지는 한계도 나타나는데, 바로 GET Method만을 사용할 수 있다는 점입니다. 이것은 JSONP가 <script> 요소를 사용하기 때문에 가지는 숙명적인 한계라고 할 수 있습니다.

 

jQuery에서 JSONP 사용하기

금번 포스팅에서는 JSONP의 원리를 설명하기 위하여 Live Javascript로 예제코드를 작성하였지만, 실무에서는 대부분 jQuery를 이용하게 될 것입니다. 위 예제파일의 find() 함수를 jQuery로 변경하면 아래와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function find()
    var s = encodeURIComponent(document.getElementById('str').value);
    
    $.ajax({
        dataType: "jsonp",
        url: "http://b.epiloum.net/find.php",
        type: "GET",
        data: {'s':s},
        success: function(data){
            loadList(data);
        }
    });
 
    return false;
}

jQuery에서는 위처럼 $.ajax() 스펙을 이용하여 평소에 Ajax를 구현하던 것과 동일한 모양으로 JSONP를 구현할 수 있습니다. Ajax와 다른 점은 단지 dataType 값을 “jsonp”로 놓았다는 것 뿐입니다. 위 예제코드를 실행해보면 success 함수가 콜백함수의 역할을 하게 되는 것을 볼 수 있습니다.

다만 이렇게 JSONP를 구현할 경우 3가지 한계가 있습니다. 첫 번째로 type 값은 무조건 GET으로 고정해야 합니다. POST 등으로 설정할 경우, data 값에서 설정한 파라메터들이 실제로 전달되지 않아 정상작동하지 않는 경우가 있습니다.  두 번째로 JSONP를 사용할 경우에는 통신실패시 처리함수인 error 값은 사용할 수 없음을 유념해야 할 것입니다. 마지막으로 url 파라미터로 통신할 파일에서 콜백함수를 받는 GET 파라미터는 반드시 callback으로 고정되어야 합니다.

Cross domain JSON 원리

현재 페이지의 스크립트에서 다른 서버로 Ajax 호출을 시도하는 것은 허용되지 않습니다. 이것을 cross domain JSON을 이용하여 해결할 수 있는데 다음 URL에서 cross domain JSON을 이용한 원격 호출 방법과 간단한 JavaScript 유틸리티를 제시합니다.
그럼 어떻게 JSON을 이용하여 다른 서버의 서비스를 호출할 수 있는지 살펴보겠습니다. 원리를 알면 쉽게 나에게 적합한 유틸리티를 만들수 있을 겁니다.
스크립트 태그
다음은 스크립트 태그입니다. 보통 아래와 같이 사용합니다.
test.js
 
alert(‘OK’);
test.html
<script type=”text/javascript” src=”js/test.js”></script>
그럼 js 디렉토리에 아래와 같은 JavaScript를 생성하는 jsp를 만들고 스크립트 태그에 다음과 같이 수정해봅니다.
test.jsp
 
alert(‘<%=System.getProperty(“os.name”)%>’);
test.html
<script type=”text/javascript” src=”http://userhost:port/js/test.jsp”></script>
System.getProperty(“os.name”)은 Host의 OS 이름을 가져오는 Java 코드이고 서버에서 실행되는 코드입니다.
위와 같이 하면 해당 서버의 OS 이름이 나타날 겁니다.
스크립트 src의 URL에 제약이 없다
위의 test.jsp가 이 서버말고 다른 서버(도메인)에 있더라도 동작합니다.
그럼 test.jsp를 다른 서버에 올려놓고 다음과 같이 스크립트 태그를 수정해 봅니다.
test.html
<script type=”text/javascript” src=”http://remote:port/js/test.jsp”></script>
원격 서버의 OS 이름이 나타날 겁니다.
그럼 test.jsp를 다음과 같은 스크립트를 생성하도록 바꾸고, test.html에는 getHostOs라는 JavaScript 함수를 만들어 놓습니다.
(내서버) test.html
<script type=”text/javascript”>
function getHostOs(response) {
alert(response.osName);
}
</script>
<script type=”text/javascript” src=”http://remote:port/js/test.jsp”></script>
(원격서버) test.jsp
getHostOs({osName:'<%=System.getProperty(“os.name”)%>’});
7번째 줄 javascript 태그에서 원격에서 생성된 스크립트를 실행합니다. 원격 서버에서 생성된 스크립트를 보니 JSON 데이터를 만들고 그걸 파라메터로 getHostOs 라는 함수를 호출하는군요. 이 함수는 이미 페이지에 준비되어 있습니다. (callback 함수라고 합니다.) 즉 아래와 동일한 결과죠.
<script type=”text/javascript”>
function getHostOs(response) {
alert(response.osName);
}
</script>
<script type=”text/javascript”>
getHostOs({osName:’Linux’});
</script>
여기서 관심있게 볼 부분은 8번째 줄 {osName:’Linux’}이 원격에서 생성한 JSON 데이터라는 것입니다.
실전
원격의 JSON 데이터를 가지고 오기 위해서는 <script type… src=”…”></script> 부분이 필요합니다.
원격 서비스 호출을 하는 JavaScript 유틸리티를 만들려면 원격 호출할 때마다 위 방식의 스크립트 태그가 필요하니 동적으로 생성하면 됩니다.
scriptObj = document.createElement(“script”);
scriptObj.setAttribute(“type”, “text/javascript”);
scriptObj.setAttribute(“charset”, “utf-8”);
scriptObj.setAttribute(“src”, remoteUrl);
원격 서비스마다 응답 JSON을 처리하는 방법이 다르므로 callback 함수 이름은 요청마다 다르게 해주어야 하며 원격 서버는 callback 이름을 파라메터로 받아 그 함수이름으로 JSON을 파라메터로 넘기는 스크립트를 생성해주어야 합니다. 즉 callback 함수로 감싸면 됩니다.
http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html  기사에 있는 예제 http://www.xml.com/2005/12/21/examples/jsr_class.zip 소스를 참고하시면 JSON을 이용한 자신만의 cross domain 호출 유틸리티를 만들 수 있을 겁니다.

 

HTTP Response Code 정리

Response Code 에 따라서 어떤 응답을 나타내는지 정리

 Response Class Code   Response Class 의미  설명
 1  Informational (정보)  리퀘스트를 받고, 처리 중에 있음.
 2  Success (성공)  리퀘스트를 정상적으로 처리함.
 3  Redirection (리디렉션)  리퀘스트 완료를 위해 추가 동작이 필요함.
 4  Client Error (클라이언트 오류)  클라이언트 요청을 처리할 수 없어 오류 발생
 5  Server Error (서버 오류)  서버에서 처리를 하지 못하여 오류 발생

4번과 5번은 에러이기는 한데, 간단히 차이점을 설명하자면 4xx 에러는 클라이언트의 잘못된 요청으로 서버에서 처리하지 못한 것이고, 5xx 에러는 클라이언트의 요청은 문제가 없으나, 서버에서 처리중에 서버 문제로 인해 오류가 발생한 것이라고 생각하시면 됩니다.

아래는 자주 접하는 코드를 위주로 작성하였고, 더 상세한 정보는 아래 참고 자료의 위키피디아 링크를 참조해주세요.~

 

200 번대 응답(Response) : 성공(Success)

200 OK * 요청 정상 처리.
204 No Content * 요청 정상 처리하였지만, 돌려줄 리소스 없음.

* 응답에 어떠한 엔티티 바디(Entity Body)도 포함하지 않음.

* 서버에서 처리 후, 클라이언트에 정보를 보낼 필요가 없는 경우 사용.

206 Partial Content * Range가 지정된 요청인 경우, 지정된 범위만큼의 요청을 받았다는 것을 알려줌.

 

* 300 번대 응답(Response) : 리디렉션(Redirection)

301 Moved Permanently * 요청된 리소스에는 새로운 URI가 지정되어 있기 때문에, 이후로는 새 URI를 사용해야 한다는 것을 나타냄. (영구적인 URI 변경)
302 Found * 요청된 리소스에는 새로운 URI가 지정되어 있기 때문에, 이후로는 새 URI를 사용해야 한 다는 것을 나타냄. 301과 유사하지만, 302는 일시적인 URI 이동)
303 See Other * 이 응답은 요청에 대한 리소스는 다른 URI에 있기 때문에 GET 메서드를 사용해서 얻어야 한다는 것을 나타냄. 302 코드와 같지만, 303은 리디렉션 위치를 GET 메서드를 통해 얻어야 한다고 명확하게 되어 있음.
304 Not Modified * 요청한 리소스가 마지막 요청 이후 변경된 적이 없기 때문에 기존 클라이언트의 로컬 캐시 리소스를 사용하도록 알려줌.

300번대로 분류되어 있지만, 리디렉션과는 관계없는 처리를 함.

307 Temporary Redirect * 임시로 페이지를 리다이렉트 함.

 

* 400 번대 응답(Response) : 클라이언트 에러 (Client Error)

400 Bad Request * 클라이언트의 요청 구문이 잘못됨.

* 브라우저는 이 응답을 200 OK 응답과 동일한 형태로 취급함.

401 Unauthorized * 요청 처리를 위해 HTTP 인증(BASIC 인증, DIGEST 인증) 정보가 필요함을 알려줌.

접근 허용을 차단함. 최초 요청에는 인증 다이얼로그 표시하고, 두번째는 인증 실패 응답을 보냄.

403 Forbidden * 접근 금지 응답. Directory Listing 요청(서버 파일 디렉토리 목록 표시) 및 관리자 페이지 접근 등을 차단하는 경우의 응답. (파일 시스템 퍼미션 거부, 허가 되지 않은 IP 주소를 통한 액세스의 거부 등)

* 서버는 엔티티 바디에 접근 거부에 대한 이유를 명시하여 보낼 수 있음.

404 Not Found * 클라이언트가 요청한 리소스가 서버에 없음
405 Mothod Not Allowed * 허용되지 않는 HTTP 메서드를 사용함.

 

* 500 번대 응답(Response) : 서버 에러 (Server Error)

500 Internal Server Error * 서버에서 클라이언트 요청을 처리 중에 에러가 발생함.
503 Service Unavailable * 서버가 일시적으로 요청을 처리할 수 없음.

* 서버가 과부하 상태이거나 점검중이므로 요청을 처리할 수 없음을 알려줌.

504 Gateway Timeout * 서버를 통하는 게이트웨이에 문제가 발생하여 시간이 초과됨.
505 HTTP Version Not Supported * 해당 HTTP 버전에서는 지원되지 않는 요청임을 알려줌.

 

MSSQL에서 MSSQL Linked Server 설정

*. 연결된 서버 설정 창 “일반” 텝에서 SQL Server Native Client 선택 후 데이터 원본에 IP,PORT 입력

  • 연결된 서버 설정 창 “보안” 텝에서 “다음 보안 컨텍스트를 사용하여 연결” 선택 후 ID/PW 입력

SELECT * FROM OPENQUERY(AKIS_HR, ‘SELECT * FROM [dbo].[Table name]’) WHERE COMPANY_CODE IS NOT NULL;

 

Apache Web Server 2.4 에 HTTPS 적용하기 (CentOS)

설정방법

  1. 의존패키지 설치하기
    sudo yum install openssl-devel
    
  2. Apache 모듈 포함하여 재설치
    CentOS 7 에서 Apache Web Server 2.4 설치하기 참고하여 진행

    sudo ./configure --prefix=[Apache 설치된 디렉토리] --with-apr=[Apache 설치된 디렉토리]/bin/apr-1-config --enable-ssl --with-ssl=/usr/bin/openssl
    sudo make
    sudo make install
    

    prefix를 다른 위치로 지정하여 설치 후 SSL 모듈만 가져와서 사용하는것이 더 안전합니다.

    1. Apache 설정 변경하기
      vi [Apache 설치된 디렉토리]/conf/httpd.conf
      

      httpd.conf 파일에 수정할 내용

      LoadModule socache_shmcb_module modules/mod_socache_shmcb.so //주석 해제
      LoadModule ssl_module modules/mod_ssl.so //추가
      LoadModule rewrite_module modules/mod_rewrite.so //추가 (HTTPS로 리다이렉트시 사용 필요하신 분만 사용하세요.)
      Include conf/extra/httpd-ssl.conf //주석 해제
      
    2. HTTP 접속시 HTTPS로 리다이렉트 하기 위해 httpd.conf파일 마지막에 추가
      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{HTTPS} off
      RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [C]
      </IfModule>
      
  3. OpenSSL 인증서 생성하기
    GitLab에 HTTPS 보안 적용을 위한 OpenSSL 설정하기 참고하여 생성
  4. Apache SSL 관련 부분 설정 변경하기
    vi [Apache 설치된 디렉토리]/conf/extra/httpd-ssl.conf
    

    httpd-ssl.conf 파일에 수정할 내용

    JkMountCopy on //<VirtualHost _default_:443>아래에 추가
    DocumentRoot //주석처리
    SSLCertificateFile "[인증서 설치된 디렉토리]/[인증서 이름].crt"
    SSLCertificateKeyFile "[인증서 설치된 디렉토리]/[인증서 이름].key"
    
  5. Tomcat 설정 변경하기
    vi [Tomcat 설치된 디렉토리]/conf/server.xml
    

    server.xml에 변경할 내용

    SSLEngine=off” //기존 "off"를 “on”변경
    
  6. 방화벽 설정하기
    sudo firewall-cmd --add-service=https --permanent
    sudo firewall-cmd --reload
    
  7. Apache, Tomcat 재시작

 Windows 7 Apache와 Tomcat 연동 – 로드 밸런싱

환경 설정

Tomcat 7

Apache 2.4.29

OS windows 7 Win64

 

리케이션을 여러대의 Tomcat으로 구동하는 방식입니다.

Apache 설치

https://www.apachelounge.com/download/

Apache 2.4.29 Win64 용 httpd를 다운받습니다.

이때 mod_jk 파일 mod_jk-1.2.42-win64-VC15.zip도 같이 받으셔야 합니다.

Apache 버전과 Mod_jk 버전이 일치하지 않은경우 

Apache 설치후 구동이 되지 않을수 있습니다.

꼭 호환이 되는 Apache ,Mod_jk 파일을 다운 받으셔야 합니다.

원하는 경로에 Apache 압축을 풀어줍니다.

mod_jk 역시 압축을 풀어줍니다.

mod_jk.so 파일을 

Apache24\moudle 경로에

복사 / 붙여넣기합니다.

시스템 속성 -> 환경변수 설정

Apache 폴더가 존재하는 경로를 입력해줍니다.

C:\Apache24\bin

환경설정 이후

CMD Dos모드로 들어가 

Apache 설치 : httpd -k install

Apache 버전확인 : httpd -v

명령어를 통해 확인합니다.

Apache 설정모드

Apache24\conf 경로 이동후

httpd.conf 파일을 편집합니다.

Editplus 또는 메모장 활용

ServerRoot 수정

Apache 설치경로

ServerName 수정

window -> 서비스 -> Apache24 구동 후 확인

구동이 도지 않으면 Apache24 및 mod_jk를 확인해야 합니다.

Tomcat 로드 밸런싱 설정

저는 Tomcat을 2개 사용할것 입니다.

설치 된 Tomcat 경로로 이동합니다.

Tomcat 설치 경로 이동 후

was1 / was2 라는 빈 폴더를 생성합니다.

Conf / logs / webapps / work 폴더를 복사합니다.

was1 / was2 를 따로 따로 구동하기 위해 필요한 폴더입니다.

기존에 있던 폴더를 복사 하시면 됩니다.

저는 그냥 모든 폴더/파일을 복사 붙여넣기 하였습니다.

물론 Server쪽 환경 설정할때는

Conf / logs / webapps / work 폴더만 붙여넣기 하였습니다.

was1\conf\

Server.xml파일을 편집합니다.

 

<?xml version=’1.0′ encoding=’utf-8′?>

<Server port=”8005″ shutdown=”SHUTDOWN”>

  <Listener className=”org.apache.catalina.startup.VersionLoggerListener” />

  <Listener className=”org.apache.catalina.core.AprLifecycleListener” SSLEngine=”on” />

  <Listener className=”org.apache.catalina.core.JasperListener” />

  <Listener className=”org.apache.catalina.core.JreMemoryLeakPreventionListener” />

  <Listener className=”org.apache.catalina.mbeans.GlobalResourcesLifecycleListener” />

  <Listener className=”org.apache.catalina.core.ThreadLocalLeakPreventionListener” />

  <GlobalNamingResources>

    <Resource name=”UserDatabase” auth=”Container” type=”org.apache.catalina.UserDatabase” description=”User database that can be updated and saved” factory=”org.apache.catalina.users.MemoryUserDatabaseFactory”

              pathname=”conf/tomcat-users.xml” />

  </GlobalNamingResources>

  <Service name=”Catalina”>

<Connector port=”8080″ protocol=”HTTP/1.1″ connectionTimeout=”20000″ redirectPort=”8443″/>

<Connector port=”7591″ maxHttpHeaderSize=”8192″ maxKeepAliveRequests=”-1″ maxThreads=”1000″ minSpareThreads=”500″ maxSpareThreads=”500″ enableLoopups=”false” redirectPort=”8443″ acceptCount=”500″

compression=”on” compressionMinSize=”2048″ noCompressionUserAgents=”gozilla.graviata” compressableMimeType=”text/html,text/xml,text/plain,text/javascript,text/css”

connectionTimeout=”600000″ disabledUploadTimeout=”true” Server=”” protocol=”AJP/1.3″  />

<Engine jvmRoute=”tomcat1″ name=”Catalina” defaultHost=”localhost”>

<Realm className=”org.apache.catalina.realm.LockOutRealm”>

<Realm className=”org.apache.catalina.realm.UserDatabaseRealm” resourceName=”UserDatabase”/>

</Realm>

<Host name=”localhost”  appBase=”C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81\webapps” unpackWARs=”true” autoDeploy=”true”>

 <Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs” prefix=”was1″ suffix=”.txt”  pattern=”%h %l %u %t &quot;%r&quot; %s %b” />

<Context crossContext=”true” path=”” docBase=”/KorailBim” reloadable=”true”></Context>

</Host>

<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster” channelSendOptions=”8″>

<Manager className=”org.apache.catalina.ha.session.DeltaManager” expireSessionsOnShutdown=”false” notifyListenersOnReplication=”true” />

<Channel className=”org.apache.catalina.tribes.group.GroupChannel”>

<Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.4″ port=”45564″ frequency=”500″ dropTime=”3000″ />

<Receiver className=”org.apache.catalina.tribes.transport.nio.NioReceiver” address=”auto” port=”4000″ autoBind=”100″ selectorTimeout=”5000″ maxThreads=”6″ />

<Sender className=”org.apache.catalina.tribes.transport.ReplicationTransmitter”>

<Transport className=”org.apache.catalina.tribes.transport.nio.PooledParallelSender” />

</Sender>

<Interceptor className=”org.apache.catalina.tribes.group.interceptors.TcpFailureDetector” />

<Interceptor className=”org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor” />

</Channel>

<Valve className=”org.apache.catalina.ha.tcp.ReplicationValve” filter=”” />

<Valve className=”org.apache.catalina.ha.session.JvmRouteBinderValve” />

<Deployer className=”org.apache.catalina.ha.deploy.FarmWarDeployer” tempDir=”/tmp/war-temp/” deployDir=”/tmp/war-deploy/” watchDir=”/tmp/war-listen/” watchEnabled=”false” />

<ClusterListener className=”org.apache.catalina.ha.session.ClusterSessionListener” />

</Cluster>

</Engine>

 </Service>

</Server>

—————————————————————————–

웹 어플리케이션이 구동될 Webapps\ROOT으로 이동합니다.

이 경로는 Tomcat -> Server.xml -> appBase 에 설정된 경로의 Root을 사용하면 됩니다.

Web.xml 편집모드로 들어가

<distributable/>

추가해줍니다.

Was2\conf

Server.xml

역시 위와 동일하게 처리해줍니다.

<?xml version=’1.0′ encoding=’utf-8′?>

<Server port=”8006″ shutdown=”SHUTDOWN”>

  <Listener className=”org.apache.catalina.startup.VersionLoggerListener” />

  <Listener className=”org.apache.catalina.core.AprLifecycleListener” SSLEngine=”on” />

  <Listener className=”org.apache.catalina.core.JasperListener” />

  <Listener className=”org.apache.catalina.core.JreMemoryLeakPreventionListener” />

  <Listener className=”org.apache.catalina.mbeans.GlobalResourcesLifecycleListener” />

  <Listener className=”org.apache.catalina.core.ThreadLocalLeakPreventionListener” />

  <GlobalNamingResources>

    <Resource name=”UserDatabase” auth=”Container” type=”org.apache.catalina.UserDatabase”  description=”User database that can be updated and saved” factory=”org.apache.catalina.users.MemoryUserDatabaseFactory”

              pathname=”conf/tomcat-users.xml” />

  </GlobalNamingResources>

  <Service name=”Catalina”>

        <Connector port=”8081″ protocol=”HTTP/1.1″ connectionTimeout=”20000″ redirectPort=”8443″/>

<Connector port=”8090″ maxHttpHeaderSize=”8192″ maxKeepAliveRequests=”-1″ maxThreads=”1000″ minSpareThreads=”500″ maxSpareThreads=”500″ enableLoopups=”false” redirectPort=”8443″ acceptCount=”500″

compression=”on” compressionMinSize=”2048″ noCompressionUserAgents=”gozilla.graviata” compressableMimeType=”text/html,text/xml,text/plain,text/javascript,text/css”

connectionTimeout=”600000″ disabledUploadTimeout=”true” Server=”” protocol=”AJP/1.3″  />

<Engine jvmRoute=”tomcat2″ name=”Catalina” defaultHost=”localhost”>

<Realm className=”org.apache.catalina.realm.LockOutRealm”>

<Realm className=”org.apache.catalina.realm.UserDatabaseRealm” resourceName=”UserDatabase”/>

</Realm>

<Host name=”localhost”  appBase=”C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81\webapps” unpackWARs=”true” autoDeploy=”true”>

 <Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs”

               prefix=”was2″ suffix=”.txt”

               pattern=”%h %l %u %t &quot;%r&quot; %s %b” />

<Context crossContext=”true” path=”” docBase=”/KorailBim” reloadable=”true”></Context>

</Host>

<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster” channelSendOptions=”8″>

<Manager className=”org.apache.catalina.ha.session.DeltaManager” expireSessionsOnShutdown=”false” notifyListenersOnReplication=”true” />

<Channel className=”org.apache.catalina.tribes.group.GroupChannel”>

<Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.4″ port=”45564″ frequency=”500″ dropTime=”3000″ />

<Receiver className=”org.apache.catalina.tribes.transport.nio.NioReceiver” address=”auto” port=”4000″ autoBind=”100″ selectorTimeout=”5000″ maxThreads=”6″ />

<Sender className=”org.apache.catalina.tribes.transport.ReplicationTransmitter”>

<Transport className=”org.apache.catalina.tribes.transport.nio.PooledParallelSender” />

</Sender>

<Interceptor className=”org.apache.catalina.tribes.group.interceptors.TcpFailureDetector” />

<Interceptor className=”org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor” />

</Channel>

<Valve className=”org.apache.catalina.ha.tcp.ReplicationValve” filter=”” />

<Valve className=”org.apache.catalina.ha.session.JvmRouteBinderValve” />

<Deployer className=”org.apache.catalina.ha.deploy.FarmWarDeployer” tempDir=”/tmp/war-temp/” deployDir=”/tmp/war-deploy/” watchDir=”/tmp/war-listen/” watchEnabled=”false” />

<ClusterListener className=”org.apache.catalina.ha.session.ClusterSessionListener” />

</Cluster>

</Engine>

 </Service>

</Server>

———————————————-
Server Port / Connector Port / Cluster Port는
 
was1\Server.xml Port와 중복되지 않게 설정합니다.
 
appBase는 웹 어플리케이션의 위치이기 때문에 
Was1/Was2로 따로 설정해도 무방하지만
배포 처리를 각각해줘야 하기 때문에 
저는 메인 Tomcat 위치로 설정했습니다.
 

다시 Apache24\httpd.conf 파일을 편집하여

Directory경로를 수정해 줍니다.

Apache가 처리할 소스 경로로 Tomcat의 웹 어플리케이션이 존재하는 최상위 폴더를 지정했습니다.

DocumentRoot “C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81\webapps”

<Directory “C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81\webapps”>

    Require all granted <- 추가

Options Indexes FollowSymLinks

AllowOverride None

Require all granted

</Directory>

Apache24 와 Tomcat의 로드 밸런싱을 위한 설정을 해줘야합니다.

LoadModule jk_module modules/mod_jk.so

JkWorkersFile conf/workers.properties

JkLogFile logs/mod_jk.log

JkLogLevel info

JkLogStampFormat “[%a %b %d %H:%M:%S %Y] ”

JkRequestLogFormat “%w %V %T”

JkMount /  loadbalancer

JkMount /* loadbalancer

AddDefaultCharset UTF-8

conf/workers.properties

파일은 사용자가 직접 빈 파일을 생성해야 합니다.

빈 파일 생성후 편집모드로 작성합니다.

worker.list=loadbalancer, status
worker.tomcat1.port=7591
worker.tomcat1.host=localhost
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=100
worker.tomcat2.port=8090
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=100
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tomcat1, tomcat2
worker.loadbalancer.method=B
# B(Busyness), R(Requests), T(Traffic)
worker.status.type=status
 
Tomcat\Server.xml에 정의한 
AJP/13  Connector의  jvmRoute의 명칭가 일치시켜 주면 됩니다.
 
was1/Server.xml -> jvmRoute=tomcat1
was1/Server.xml -> port=7591
 
was2/Server.xml -> jvmRoute=tomcat2
was2/Server.xml -> port=8090
이제 마지막으로 was1/was2 실행을 위한 Startup 작업을 해줘야 합니다.

기존에 있던

startup.bat / shutdown.bat

복사 / 붙여넣기를 통해 명칭을 변경합니다.

startup_was1.bat/shutdown_was1.bat

모두편집 모드로 들어가

set “CATALINA_HOMDE=C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81”

set “CATALINA_BASE=C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81\was1”

set “SERVER_NAME=was1”

set “JAVA_HOME=C:\Program Files\Java\jdk1.8.0_91”

추가해줍니다.

Apache 설치 및 Was1/was2 구동을 위한 경로

JDK 경로를 설정해줍니다.

————————————-

tartup_was2.bat/shutdown_was2.bat

모두편집 모드로 들어가

set “CATALINA_HOMDE=C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81”

set “CATALINA_BASE=C:\Users\User\Downloads\apache-tomcat-7.0.81-windows-x64\apache-tomcat-7.0.81\was2”

set “SERVER_NAME=was2”

set “JAVA_HOME=C:\Program Files\Java\jdk1.8.0_91”

추가해줍니다.

Apache 설치 및 Was1/was2 구동을 위한 경로

JDK 경로를 설정해줍니다.

Window의 서비스 모드에서

설치된 Apache24를 구동합니다.

마지막으로 Tomcat을 구동하고

localhost:80 포틀 접속하시면 끝이납니다.

한쪽 서버 부하로 인하여 서버가 중단 될경우

다른 한쪽 서버로 웹 어플리케이션이 연동되어

서비스를 운영하는 모드입니다.

테스트 절차는 was1/was2 구동

localhost:80 접속

was로그를 통해 구분 후 접속된 Was 내림

몇초 지난 후

localhost:80 기능 그대로 사용

다른 서버에 붙어서 접속 허용

지금까지

Window Apache Tomcat 로드 밸런싱 연동 과정이었습니다.

출처: https://seungkangmo.tistory.com/173 [Let’s Get It]

Apache24, 톰캣 8.5 연동

2.1 mod_jk 모듈 다운받기

mod_jk는 Apache24에 추가할 수 있는 모듈 중 하나로써,
Apache24에서 다른 웹컨테이너로 처리할 파일을 넘겨줄 수 있게 합니다
https://www.apachelounge.com/download/
링크로 들어가서 스크롤을 살짝 내려보면 Apache 2.4 modules VC14라는 큰 제목이 있고 그 밑에 Apache 2.4에 추가할 수 있는 모듈이 잔뜩 있습니다
그중 mod_jk-1.2.42-win64-VC14.zip
(32bit는 mod_jk-1.2.42-win32-VC14.zip) 를 다운받습니다

압축파일을 열고 mod_jk.so 를
(아파치경로)\modules 폴더 안에 복사합니다
ex) E:\Program Files\Apache24\modules\mod_jk.so

2.2 workers.properties 만들기

(아파치경로)\conf 폴더 안에 텍스트 파일을 만들고 파일 이름과 확장자를 workers.properties로 설정합니다
ex) E:\Program Files\Apache24\conf\workers.properties

workers.properties를 열어서 다음과 같이 작성합니다

worker.list=worker1 

worker.worker1.type=ajp13 

worker.worker1.host=localhost 

worker.worker1.port=8009

2.3 번까지 진행하시면, Apache24는 jsp 파일을 클라이언트로부터 요청받으면 다른 웹컨테이너에게 처리를 떠넘깁니다
이 때 다른 웹컨테이너의 포트번호 등을 작성한 것이 workers.properties 파일입니다
“일을 대신 맡아줄 객체로 worker1를 추가해라. worker1의 type은 ajp13, host는 localhost, 포트번호는 8009이다”

type=ajp13, port=8009를 가진 웹컨테이너는 톰캣이므로 worker1에 작업을 맡기면 톰캣이 그 작업을 처리하게 됩니다

ajp13, port=8009 에 대한 정보는
(톰캣 경로)\conf\server.xml에서 확인할 수 있습니다

2.3 httpd.conf 수정하기

다시
(아파치경로)\conf\httpd.conf 파일을 메모장으로 실행합니다
맨 아래로 스크롤해서 다음을 추가해줍니다

LoadModule jk_module modules/mod_jk.so 
JkWorkersFile conf/workers.properties 
JkLogFile logs/mod_jk.log 
JkLogLevel info 
JkMount /*.jsp worker1

LoadModule로 앞에서 복사해뒀던 mod_jk.so 모듈을 불러옵니다
JkWorkersFile로 작업을 맡길 녀석들의 정보가 담긴 workers.properties 파일을 불러옵니다
JkMount /*.jsp worker1 부분이 젤 중요한데,

/*.jsp: Apache24에서 다른 웹컨테이너에게 맡길 파일 종류를 작성합니다
ex1) JkMount /* worker1
-> worker1으로 지정된 웹컨테이너에게 모든 파일의 처리를 맡깁니다
ex2) JkMount /*.jsp worker1
-> worker1으로 지정된 웹컨테이너에게 jsp 파일의 처리를 맡깁니다

worker1: workers.properties에서 정의한 객체 중 하나로 파일 처리를 맡길 웹컨테이너를 의미합니다
만약 worker1으로 쓰면 worker1에게, worker2로 쓰면 worker2에게 지정한 파일 종류의 처리를 맡깁니다
※ worker1, worker2 등은 작성자가 임의로 지은 변수이름입니다….

3. 잘 된건가??

“제어판-관리도구-서비스”에서 Apache2.4, Apache Tomcat 8.5 서비스를 시작한다
위 첨부파일들을 “1. 경로 설정하기”에서 설정했던 ROOT 경로에 넣고
ex) e:/Server Projects/test.php, e:/Server Projects/test.jsp

localhost/test.php
localhost/test.jsp

를 브라우저 주소창에 쳐본다
숫자 1이 출력되면 성공한 것!
* Apache24 서버가 사용하는 포트를 이용하시면 됩니다
만약 Apache24에 8008 포트를 사용하시면….
localhost:8008/test.php, localhost:8008/test.jsp

4. 잘 안되는 사람들 유형

1. jsp 소스코드가 그대로 출력된다….
연동이 제대로 되지 않은 경우로 Apache24에서 jsp를 톰캣에게 처리를 맡기지 않고 직접 실행한 경우이다
“2.3 httpd.conf 수정”부분을 다시 한번 해본다

2. php 파일실행 시 php 파일이 실행되지 않고 다운로드된다….
Apache24가 php 파일마저 톰캣에게 처리를 맡기는 경우이다
“2.3 httpd.conf수정”에서
JkMount /*.jsp worker1
를 제대로 썼는지 확인해본다

3. 추가로 다음화면은 경로 설정을 잘못해서, 해당 경로에 없는 파일에 접근하려 할 때 나온다

상단 화면이 나타나면 톰캣8.5의 ROOT 경로가 잘못된 경우이고
하단 화면이 나타나면 Apache24의 ROOT 경로가 잘못된 경우이다
“1. 경로 설정하기”에서 경로를 잘 설정했는지 확인해보자

totoliFile Server HTTPS(SSL) 인증서 경고 없이 사용하기

**. TOTOLI 서버에 접속한 후 파일 목록의 최 하단에 위치한 rootCA 인증서를 다운로드 하세요.

1. totoli Server의 Root 인증서를 다운로드 합니다.

 

2. 다운로드 대화창(BAR)가 나타나면 [열기]를 선택합니다.

 

3. 보안 메시지 창에서 [허용]을 선택합니다.

 

4. 인증서 정보창이 열리면 [인증서 설치]버튼을 선택합니다.

 

5. 인증서 가져오기 마법사의 저장소 위치를 “로컬 컴퓨터” 로 선택 후 [다음]으로 진행 합니다.

 

6. 인증서 저장소 선택지 중 “모든 인증서를 다음 저장소에 저장”을 선택 후 [찾아보기]를 통해

인증서가 저장될 저장소 선택창을 부릅니다.

 

7. 인증서 저장소 선택창에서 “신뢰할 수 있는 루트 인증 기관” 저장소를 선택 후 [확인]을 선택합니다.

 

8. 다시 인증서 가져오기 마법사로 돌아와 [다음]으로 진행합니다.

 

9. 인증서 가져오기 마법사를 [마침]을 선택해 닫습니다.

 

10. 인증서 가저오기를 완료하였습니다. 안내 메시지 창의 [확인]을 선택합니다.

 

11. 인증서 정보창도 [확인]을 선택하여 닫습니다.

 

**. TOTOLI ROOT 인증서 설치가 완료 되었으며, 인증서를 설치한 PC 에서는 HTTPS 프로토콜로

접근시 더이상 보안 경고창이 나타나지 않게 됩니다.

 

MSSQL에서 Oracle Linked Server 설정

1. 오라클 ODAC 설치
https://www.oracle.com/technetwork/topics/dotnet/index-090165.html


– 64 비트 Oracle Data Access Components (ODAC) 다운로드 (ODAC122010_x64.zip)

2. tnsnames.ora 파일복사

설치한 경로의 sample폴더에 있는 tnsnames.ora 파일을 복사하여 Admin 폴더 아래에 붙혀넣는다.
(예 c:\oracleexe/app/oracle/product/11.2.0/server/network/admin/sample/tnsnames.ora)
3. 연결정보 입력
– tnsnames.ora 파일에 연결정보를 입력 한다.

 

 *TNS명 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = *IP주소)(PORT = *포트번호))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = *DB명)
)
)

 

 

예) TNS명 : ISM / DBName : MMC / IP:222.222.222.222 / 포트번호: 1521

ISM =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 222.222.222.222)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = MMC)
)
)
4. Inprocess허용

링크드 서버를 등록할때 다음과 같은 에러 메시지가 나올것이다.

연결된 서버 “ISM시스템’에 대한 OLE DB공급자 “OraOLEDB.Oracle”의 인스턴스를 만들 수 없습니다.
(Microsoft SQL Server, 오류:7302)

해결방법 : Inprocess 허용을 해줘야 한다.

 

연결된 서버 > OraOLEDB.Oracle 의 속성창을 연다.

 

 

 

 

5. MSSQL에 링크드서버 등록

 

 

예) 위 예제 내용을 등록

 

**. Oracle Database User / Password 설정

[새 연결된 서버 팝업창] ->[패이지선택 영역] -> [보안] -> [다음 보안 컨텍스트를 사용하여 연결]

> 원격로그인 : ID

> 암호 : PW

 

6. 5번까지 했는데 링크드서버가 등록되지 않는다면 재부팅을 해야한다.

오라클 드라이버가 재부팅을 해야 적용되는 경우도 있다. (방화벽도 체크 해보시길)