2013년 5월 12일 일요일

[javascript] 새로고침 막는 방법



<script language="javascript">
//새로 고침 방지 기능 실행
function LockF5(){
 if (event.keyCode == 116) {
  event.keyCode = 0;
  return false;
 }
}
document.onkeydown = LockF5;
</script>
[출처] F5 새로고침 방지 |작성자 minhi1000
→ IE8에서 제대로 작동 안 함(크롬에서는 작동)


*IE8에서 작동하다록 하는 방법


document.onkeydown=function(e) {
    var event = window.event || e;
    if (event.keyCode == 116) {
        event.keyCode = 0;
        alert("This action is not allowed");
        return false;
    }
}

2013년 5월 9일 목요일

[javascript] jsonStringData → html table 구조로 print하기



search버튼 눌렀을 때 server response 밑에 나오는 table 구조의 customer 정보들
servlet에서 arrayList를 json으로 포맷 변환 후, response.(바로 직전 게시글 참조)

ajax로 호출 후 response 받은 jsonString data를 화면에 print

나머지 소스는 생략하고, javascript에서 print 해주는 부분만 발췌!
------------------------------------------------------------------
function crateTableRow(row, data, cellType) {
   var cell = document.createElement(cellType);
  var textNode = document.createTextNode(data);
  cell.appendChild(textNode); row.appendChild(cell);
}


function createTableData(row, data) {
  crateTableRow(row, data, "td");
}

function createTableHeader(row, data) {
  crateTableRow(row, data, "th");
}

function displayJSON(jsonString) {
  var json = JSON.parse(jsonString); //servlet에서 넘겨준 jsonString 값을 json으로 parsing
  var table = document.createElement("table");

  var thead = document.createElement("thead");
  table.appendChild(thead);
  var row = document.createElement("tr");
  createTableHeader(row,"Name");
  createTableHeader(row,"Age");
  createTableHeader(row,"Tel");
  createTableHeader(row,"Addr");
  thead.appendChild(row);

  var tbody = document.createElement("tbody");
  table.appendChild(tbody);
  for(var i=0; i<json.customers.length; i++) {
  var row = document.createElement("tr");
  createTableData(row,json.customers[i].name);
      createTableData(row,json.customers[i].age);
createTableData(row,json.customers[i].tel);
createTableData(row,json.customers[i].addr);
tbody.appendChild(row);
}
document.getElementById("serverResponse").innerHTML = "";
  document.getElementById("serverResponse").appendChild(table); }
------------------------------------------------------------------

[java] java arraylist → JSON으로 변경하기

ajax 테스트하다 보니 text 형태로 값을 return 하던데 그럼 arraylist Type은?

바로 넘겨줄 수 있는 줄 알았더니 그게 아니더군..-_-;;
arraylist를 잘 표현할 수 있는 것이 xml, json이라는 지인의 말.
(혹시 다른 방법이 있다면 commnet 좀..;;)

그리하여 구글링 하다가 찾은 java arraylist를 json으로 변경하는 logic


클라이언트에서 ajax로 요청했을 때 자료를 손쉽게 파싱하기 위해서 json으로 클라이언트에 던져줄 때가 편할 때가 있습니다. 그래서 손쉽게 json으로 변환하는 라이브러리가 있습니다.

http://json-lib.sourceforge.net/

여기보면 json-lib라는 놈이 있는데 json으로 손쉽게 변환해주는 라이브러리입니다.


  • jakarta commons-lang 2.5
  • jakarta commons-beanutils 1.8.0
  • jakarta commons-collections 3.2.1
  • jakarta commons-logging 1.1.1
  • ezmorph 1.0.6
    이것들이 필요하다더군요. 위에 4개는 apache에 가면 있구요.
    ezmorph는 http://ezmorph.sourceforge.net/에 있습니다.

    사용법은 매우 간단합니다.
    [code]
    public class JsonTest {

     @Test
     public void Bean2Json()
     {
      MyBean myBean1 = new MyBean();
      myBean1.setId(1);
      myBean1.setName("mudchobo");
      MyBean myBean2 = new MyBean();
      myBean2.setId(2);
      myBean2.setName("shit");

      List<MyBean> mybeanList = new ArrayList<MyBean>();
      mybeanList.add(myBean1);
      mybeanList.add(myBean2);

      JSONArray jsonArray = JSONArray.fromObject(mybeanList);
      System.out.println("mybeanList - " + jsonArray);

      Map<String, Object> map = new HashMap<String, Object>();
      map.put("beanlist", jsonArray);

      JSONObject jsonObject = JSONObject.fromObject(map);
      System.out.println("json - " + jsonObject);
     }
    }
    [/code]
    Bean 2개를 List에 add를 한다음에 JSONArray라는 객체가 List를 배열로 만드는놈입니다.

    mybeanList - [{"id":1,"name":"mudchobo"},{"id":2,"name":"shit"}]

    이런식으로 만듭니다.
    저거를 JSONObject클래스를 이용해서 앞에 이름을 붙여줍니다. Map을 이용하면 됩니다
    Map을 이용해서 put에서 첫번째 인자에 이름을 넣고, 두번째 인자에 방금 생성한 Array를 넣으면 됩니다.
    그리고 JSONObject.fromObject메소드를 이용해서 생성하게 되면 이렇게 됩니다.

    json - {"beanlist":[{"id":1,"name":"mudchobo"},{"id":2,"name":"shit"}]}

    이상입니다-_-;


  • 출처 : http://mudchobo.tistory.com/275

    [ajax] 입문 예제(servlet 사용)

    <test.html>
    ------------------------------------------------------------

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Sending Request Data Using GET and POST</title>
    <script type="text/javascript">
    var xmlHttp;
    /*
    function createXMLHttpRequest() {
    if (window.ActiveXObject) {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } else if (window.XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest();
    }
    }
    */

    function createXMLHttpRequest() {
       if (window.ActiveXObject) {
           try {
               return new ActiveXObject("Msxml2.XMLHTTP");//IE 상위 버젼
           } catch (e1) {
               try {
                   return new ActiveXObject("Microsoft.XMLHTTP");//IE 하위 버젼
               } catch (e2) {
                   return null;
               }
           }
       } else if (window.XMLHttpRequest) {
           return new XMLHttpRequest();//IE 이외의 브라우저(FireFox 등)
       } else {
           return null;
       }
    }// XMLHttpRequest 객체 얻기

    function createQueryString() {
    var firstName = document.getElementById("firstName").value;
    var middleName = document.getElementById("middleName").value;
    var birthday = document.getElementById("birthday").value;

    var queryString = "firstName=" + firstName + "&middleName="
    + middleName + "&birthday=" + birthday;

    return queryString;
    }

    function doRequestUsingGET() {
    alert("doRequestUsingGET");
    xmlHttp = createXMLHttpRequest();

    var queryString = "ajaxResponseTestServlet?";
    queryString = queryString + createQueryString() + "&timeStamp="
    + new Date().getTime();
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.open("GET", queryString, true);
    xmlHttp.send(null);
    }

    function doRequestUsingPOST() {
    alert("doRequestUsingPOST");
    xmlHttp = createXMLHttpRequest();

    var url = "ajaxResponseTestServlet?timeStamp=" + new Date().getTime();
    var queryString = createQueryString();

    xmlHttp.open("POST", url, true);
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.setRequestHeader("Content-Type",
    "application/x-www-form-urlencoded;charset=utf-8");            
                                                                      → 한글 때문에
    xmlHttp.send(queryString);
    }

    function handleStateChange() {
    if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
    parseResults();
    }
    }
    }

    function parseResults() {
    var responseDiv = document.getElementById("serverResponse");
    if (responseDiv.hasChildNodes()) {
    responseDiv.removeChild(responseDiv.childNodes[0]);
    }

    var responseText = document.createTextNode(xmlHttp.responseText);
    responseDiv.appendChild(responseText);
    }
    </script>
    </head>
    <body>
    <h1>Enter your first name, middle name, and birthday:</h1>

    <table>
    <tbody>
    <tr>
    <td>First name:</td>
    <td><input type="text" id="firstName"/></td>
    </tr>
    <tr>
    <td>Middle name:</td>
    <td><input type="text" id="middleName"/></td>
    </tr>
    <tr>
    <td>Birthday:</td>
    <td><input type="text" id="birthday"/></td>
    </tr>
    </tbody>

    </table>

    <form action="#">
    <input type="button" value="Send parameters using GET"
    onclick="doRequestUsingGET();" />

    <br />
    <br />
    <input type="button" value="Send parameters using POST"
    onclick="doRequestUsingPOST();" />
    </form>
    <br />
    <h2>Server Response:</h2>
    <div id="serverResponse"></div>
    </body>
    </html>
    ------------------------------------------------------------
    인터넷에서 사용하는 소스를 가지고 테스트를 했는데, 왜 에러가 나는거니..
    (어쨌든 수정 후, 테스트 완료!)


    <ajaxResponseTestServlet>
    eclipse juno version은 web.xml이 없다.
    servlet을 생성하고 한참 web.xml을 찾았는데 java파일을 보니 annotation 마크와 함께 뭔가가 생성. (익숙했던 방법이 아니라 멍....;;)
    ------------------------------------------------------------

    package test;

    import java.io.IOException;
    import java.io.PrintWriter;

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    /**
     * Servlet implementation class ajaxResponseTestServlet
     */
    @WebServlet("/ajaxResponseTestServlet")
    public class ajaxResponseTestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void processRequest(HttpServletRequest request,
    HttpServletResponse response, String method)
    throws ServletException, IOException {

    // Set content type of the response to text/xml
    response.setContentType("text/xml");
    response.setCharacterEncoding("utf-8"); → 한글 때문에

    // Get the user's input
    String firstName = request.getParameter("firstName");
    String middleName = request.getParameter("middleName");
    String birthday = request.getParameter("birthday");

    // Create the response text
    String responseText = "Hello " + firstName + " " + middleName
    + ". Your birthday is " + birthday + "." + " [Method: "
    + method + "]";

    // Write the response back to the browser
    PrintWriter out = response.getWriter();
    out.println(responseText);
    // Close the writer
    out.close();
    }

    /**
    * @see HttpServlet#HttpServlet()
    */
    public ajaxResponseTestServlet() {
    super();
    // TODO Auto-generated constructor stub
    }

    /**
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    *      response)
    */
    protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    System.out.println("GET");
    processRequest(request, response, "GET");
    }

    /**
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    *      response)
    */
    protected void doPost(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    System.out.println("POST");
    processRequest(request, response, "POST");
    }

    }
    ------------------------------------------------------------

    2012년 10월 10일 수요일

    [JSP] xml 포맷 그대로 표현하기

    기존 JSP에서 xml데이터 포맷 그대로 보여주고 싶을 때
    (실제로 html과 xml은 언어 자체가 달라서 두 개를 같이 표현을 해 줄 수가 없다. 찾아보니 그러한 기능을 js와 css를 사용해서 구현한 사이트가 있어서 샘플을 만들었다. 
    구글링 만세!)

    -------------------------------------------------------
    index.jsp
    -------------------------------------------------------
    <%@ page language="java" contentType="text/html; charset=EUC-KR"
        pageEncoding="EUC-KR"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
    <title>Insert title here</title>
    </head>
    <body>
    <div id="XMLHolder"></div>
    <LINK href='XMLDisplay.css' type='text/css' rel='stylesheet'>
    <script type='text/javascript' src='XMLDisplay.js'></script>
    <script>LoadXML('XMLHolder','test.xml');</script>
    </body>
    </html>

    **테스트용이었으므로 css파일, js파일, jsp파일 모두 같은 위치에 배치

    -------------------------------------------------------
    XMLDisplay.js
    -------------------------------------------------------
    /* Copyright (c) 2007 Lev Muchnik <LevMuchnik@gmail.com>. All rights reserved.
     * You may copy and modify this script as long as the above copyright notice,
     * this condition and the following disclaimer is left intact.
     * This software is provided by the author "AS IS" and no warranties are
     * implied, including fitness for a particular purpose. In no event shall
     * the author be liable for any damages arising in any way out of the use
     * of this software, even if advised of the possibility of such damage.
     * $Date: 2007-10-03 19:08:15 -0700 (Wed, 03 Oct 2007) $
     */

    function LoadXML(ParentElementID,URL) 
    {
    var xmlHolderElement = GetParentElement(ParentElementID);
    if (xmlHolderElement==null) { return false; }
    ToggleElementVisibility(xmlHolderElement);
    return RequestURL(URL,URLReceiveCallback,ParentElementID);
    }
    function LoadXMLDom(ParentElementID,xmlDoc) 
    {
    if (xmlDoc) {
    var xmlHolderElement = GetParentElement(ParentElementID);
    if (xmlHolderElement==null) { return false; }
    while (xmlHolderElement.childNodes.length) { xmlHolderElement.removeChild(xmlHolderElement.childNodes.item(xmlHolderElement.childNodes.length-1)); }
    var Result = ShowXML(xmlHolderElement,xmlDoc.documentElement,0);
    var ReferenceElement = document.createElement('div');
    var Link = document.createElement('a');
    Link.setAttribute('href','http://www.levmuchnik.net/Content/ProgrammingTips/WEB/XMLDisplay/DisplayXMLFileWithJavascript.html');
    //var TextNode = document.createTextNode('Source: Lev Muchnik');
    Link.appendChild(TextNode);

    xmlHolderElement.appendChild(Link);
    return Result;
    }
    else { return false; }
    }
    function LoadXMLString(ParentElementID,XMLString) 
    {
    xmlDoc = CreateXMLDOM(XMLString);
    return LoadXMLDom(ParentElementID,xmlDoc) ;
    }
    ////////////////////////////////////////////////////////////
    // HELPER FUNCTIONS - SHOULD NOT BE DIRECTLY CALLED BY USERS
    ////////////////////////////////////////////////////////////
    function GetParentElement(ParentElementID)
    {
    if (typeof(ParentElementID)=='string') { return document.getElementById(ParentElementID); }
    else if (typeof(ParentElementID)=='object') { return ParentElementID;} 
    else { return null; }
    }
    function URLReceiveCallback(httpRequest,xmlHolderElement)
    {
     try {
                if (httpRequest.readyState == 4) {
                    if (httpRequest.status == 200) {
    var xmlDoc = httpRequest.responseXML;
    if (xmlHolderElement && xmlHolderElement!=null) {
    xmlHolderElement.innerHTML = '';
    return LoadXMLDom(xmlHolderElement,xmlDoc);
    }
                    } else {
                        return false;
                    }
                }
            }
            catch( e ) {
                return false;
            }
    }
    function RequestURL(url,callback,ExtraData) { // based on: http://developer.mozilla.org/en/docs/AJAX:Getting_Started
            var httpRequest;
            if (window.XMLHttpRequest) { // Mozilla, Safari, ...
                httpRequest = new XMLHttpRequest();
                if (httpRequest.overrideMimeType) { httpRequest.overrideMimeType('text/xml'); }
            } 
            else if (window.ActiveXObject) { // IE
                try { httpRequest = new ActiveXObject("Msxml2.XMLHTTP");   } 
                catch (e) {
      try { httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } 
      catch (e) {}
                }
            }
            if (!httpRequest) { return false;   }
            httpRequest.onreadystatechange = function() { callback(httpRequest,ExtraData); };
            /* xml위치 : /WebContent/file/ */
            httpRequest.open('GET', "http://localhost:8080/Text/file/"+url, true);
            httpRequest.send('');
    return true;
        }
    function CreateXMLDOM(XMLStr) 
    {
    if (window.ActiveXObject)
    {
     xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); 
     xmlDoc.loadXML(XMLStr);
     return xmlDoc;
    }
    else if (document.implementation && document.implementation.createDocument)  {
     var parser=new DOMParser();
     return parser.parseFromString(XMLStr,"text/xml");
    }
    else {
    return null;
    }
    }

    var IDCounter = 1;
    var NestingIndent = 40;
    function ShowXML(xmlHolderElement,RootNode,indent)
    {
    if (RootNode==null || xmlHolderElement==null) { return false; }
    var Result  = true;
    var TagEmptyElement = document.createElement('div');
    TagEmptyElement.className = 'Element';
    TagEmptyElement.style.position = 'relative';
    TagEmptyElement.style.left = NestingIndent+'px';
    if (RootNode.childNodes.length==0) { 
        var ClickableElement = AddTextNode(TagEmptyElement,'','Clickable') ;
        ClickableElement.id = 'div_empty_' + IDCounter;  
        AddTextNode(TagEmptyElement,'<','Utility') ;
        AddTextNode(TagEmptyElement,RootNode.nodeName ,'NodeName') 
        for (var i = 0; RootNode.attributes && i < RootNode.attributes.length; ++i) {
          CurrentAttribute  = RootNode.attributes.item(i);
          AddTextNode(TagEmptyElement,' ' + CurrentAttribute.nodeName ,'AttributeName') ;
          AddTextNode(TagEmptyElement,'=','Utility') ;
          AddTextNode(TagEmptyElement,'"' + CurrentAttribute.nodeValue + '"','AttributeValue') ;
        }
        AddTextNode(TagEmptyElement,' />') ;
        xmlHolderElement.appendChild(TagEmptyElement);
        //SetVisibility(TagEmptyElement,true);    
    }
    else { // mo child nodes
        
        var ClickableElement = AddTextNode(TagEmptyElement,'+','Clickable') ;
        ClickableElement.onclick  = function() {ToggleElementVisibility(this); }
        ClickableElement.id = 'div_empty_' + IDCounter;
        AddTextNode(TagEmptyElement,'<','Utility') ;
        AddTextNode(TagEmptyElement,RootNode.nodeName ,'NodeName') 
        for (var i = 0; RootNode.attributes && i < RootNode.attributes.length; ++i) {
          CurrentAttribute  = RootNode.attributes.item(i);
          AddTextNode(TagEmptyElement,' ' + CurrentAttribute.nodeName ,'AttributeName') ;
          AddTextNode(TagEmptyElement,'=','Utility') ;
          AddTextNode(TagEmptyElement,'"' + CurrentAttribute.nodeValue + '"','AttributeValue') ;
        }

        AddTextNode(TagEmptyElement,'>  </','Utility') ;
        AddTextNode(TagEmptyElement,RootNode.nodeName,'NodeName') ;
        AddTextNode(TagEmptyElement,'>','Utility') ;
        xmlHolderElement.appendChild(TagEmptyElement);
        SetVisibility(TagEmptyElement,false);
        //----------------------------------------------
        
        var TagElement = document.createElement('div');
        TagElement.className = 'Element';
        TagElement.style.position = 'relative';
        TagElement.style.left = NestingIndent+'px';
        ClickableElement = AddTextNode(TagElement,'-','Clickable') ;
        ClickableElement.onclick  = function() {ToggleElementVisibility(this); }
        ClickableElement.id = 'div_content_' + IDCounter;
        ++IDCounter;
        AddTextNode(TagElement,'<','Utility') ;
        AddTextNode(TagElement,RootNode.nodeName ,'NodeName') ;
        
        for (var i = 0; RootNode.attributes && i < RootNode.attributes.length; ++i) {
            CurrentAttribute  = RootNode.attributes.item(i);
            AddTextNode(TagElement,' ' + CurrentAttribute.nodeName ,'AttributeName') ;
            AddTextNode(TagElement,'=','Utility') ;
            AddTextNode(TagElement,'"' + CurrentAttribute.nodeValue + '"','AttributeValue') ;
        }
        AddTextNode(TagElement,'>','Utility') ;
        TagElement.appendChild(document.createElement('br'));
        var NodeContent = null;
        for (var i = 0; RootNode.childNodes && i < RootNode.childNodes.length; ++i) {
          if (RootNode.childNodes.item(i).nodeName != '#text') {
            Result &= ShowXML(TagElement,RootNode.childNodes.item(i),indent+1);
          }
          else {
            NodeContent =RootNode.childNodes.item(i).nodeValue;
          }
        }
        if (RootNode.nodeValue) {
          NodeContent = RootNode.nodeValue;
        }
        if (NodeContent) {
          var ContentElement = document.createElement('div');
          ContentElement.style.position = 'relative';
          ContentElement.style.left = NestingIndent+'px';
          AddTextNode(ContentElement,NodeContent ,'NodeValue') ;
          TagElement.appendChild(ContentElement);
        }
        AddTextNode(TagElement,'  </','Utility') ;
        AddTextNode(TagElement,RootNode.nodeName,'NodeName') ;
        AddTextNode(TagElement,'>','Utility') ;
        xmlHolderElement.appendChild(TagElement);
      }
    // if (indent==0) { ToggleElementVisibility(TagElement.childNodes(0)); } - uncomment to collapse the external element
    return Result;
    }
    function AddTextNode(ParentNode,Text,Class) 
    {
    NewNode = document.createElement('span');
    if (Class) {  NewNode.className  = Class;}
    if (Text) { NewNode.appendChild(document.createTextNode(Text)); }
    if (ParentNode) { ParentNode.appendChild(NewNode); }
    return NewNode;
    }
    function CompatibleGetElementByID(id)
    {
    if (!id) { return null; }
    if (document.getElementById) { // DOM3 = IE5, NS6
    return document.getElementById(id);
    }
    else {
    if (document.layers) { // Netscape 4
    return document.id;
    }
    else { // IE 4
    return document.all.id;
    }
    }
    }
    function SetVisibility(HTMLElement,Visible)
    {
    if (!HTMLElement) { return; }
    var VisibilityStr  = (Visible) ? 'block' : 'none';
    if (document.getElementById) { // DOM3 = IE5, NS6
    HTMLElement.style.display =VisibilityStr; 
    }
    else {
    if (document.layers) { // Netscape 4
    HTMLElement.display = VisibilityStr; 
    }
    else { // IE 4
    HTMLElement.id.style.display = VisibilityStr; 
    }
    }
    }
    function ToggleElementVisibility(Element)
    {
    if (!Element|| !Element.id) { return; }
    try {
    ElementType = Element.id.slice(0,Element.id.lastIndexOf('_')+1);
    ElementID = parseInt(Element.id.slice(Element.id.lastIndexOf('_')+1));
    }
    catch(e) { return ; }
    var ElementToHide = null;
    var ElementToShow= null;
    if (ElementType=='div_content_') {
    ElementToHide = 'div_content_' + ElementID;
    ElementToShow = 'div_empty_' + ElementID;
    }
    else if (ElementType=='div_empty_') {
    ElementToShow= 'div_content_' + ElementID;
    ElementToHide  = 'div_empty_' + ElementID;
    }
    ElementToHide = CompatibleGetElementByID(ElementToHide);
    ElementToShow = CompatibleGetElementByID(ElementToShow);
    if (ElementToHide) { ElementToHide = ElementToHide.parentNode;}
    if (ElementToShow) { ElementToShow = ElementToShow.parentNode;}
    SetVisibility(ElementToHide,false);
    SetVisibility(ElementToShow,true);
    }

    -------------------------------------------------------
    XMLDisplay.css
    -------------------------------------------------------
    @charset "utf-8";
    /* CSS Document */
    .Utility {
    color: black;
    }
    .NodeName {
    font-weight:bold;
    color: #800080;
    }
    .AttributeName 
    {
    font-weight:bold;
    color: black;
    }
    .AttributeValue
    {
    color:blue;
    }
    .NodeValue
    {
    color: black;
    }
    .Element {
    border-left-color:#FFFFFF;
    border-left-width:thin;
    border-left-style:solid;
    padding-top:0px;
    margin-top:10px;
    }
    .Clickable {
    font-weight:900;
    font-size:large;
    color: #800080;
    cursor:pointer;

    vertical-align:middle;
    }



    [oracle] sys_connect_by_path와 대체 쿼리

    SYS_CONNECT_BY_PATH
    계층형 쿼리에서 하위 레벨의 특정 컬럼들을 한 줄로 표현할 때 사용
    ex)
    LEVEL COLNM
    1         A
    2         A1
    2         A2
    2         A3
    1         B
    2         B1
    2         B2
    2         B3

    COLNM    SYS_CONNECT_BY_PATH
    A             A1,A2,A3
    B             B1,B2,B3

    모든 사람들이 접근 가능하고 테이블 create하지 않고 조회할 수 있는 scott/tiger로 작업
    ---------------------------------------------------------------------
    SYS_CONNECT_BY_PATH
    ---------------------------------------------------------------------
    SELECT
    DEPTNO
    ,SUBSTR (MAX (SYS_CONNECT_BY_PATH (ename, ',')), 2) ENAME
    FROM (
    SELECT
    DEPTNO
    ,ENAME
    ,ROW_NUMBER() OVER(PARTITION BY DEPTNO ORDER BY ENAME) AS RNO
    FROM EMP)
    START WITH RNO = 1
    CONNECT BY PRIOR RNO = RNO-1
    AND PRIOR DEPTNO = DEPTNO
    GROUP BY DEPTNO
    ORDER BY DEPTNO

    * 퍼포먼스면에서 문제가 많다고들 한다.

    꼭 계층형 쿼리를 써야 하는 부분이 아니라면, 다른 함수들을 사용하는 것이 좋겠지.

    ---------------------------------------------------------------------
    XMLELEMENT
    ---------------------------------------------------------------------
    SELECT
    DEPTNO
    ,SUBSTR(XMLAGG(XMLELEMENT(A,','|| ENAME) ORDER BY ENAME).EXTRACT('//text()'),2) ENAME
    FROM EMP
    GROUP BY DEPTNO;


    ---------------------------------------------------------------------
    WM_CONCAT
    ---------------------------------------------------------------------
    SELECT
    A.DEPTNO
    ,MAX(A.ENAME) ENAME
    FROM (
    SELECT
    DEPTNO
    ,WM_CONCAT(ENAME) OVER(PARTITION BY DEPTNO ORDER BY ENAME) ENAME
    FROM EMP) A
    GROUP BY DEPTNO;