<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>빙글빙글 돌아가는 IT 人의 하루</title>
    <link>https://vvs010.tistory.com/</link>
    <description>나의 IT관련 경험 등을 기록하는 기록장</description>
    <language>ko</language>
    <pubDate>Thu, 11 Jun 2026 08:13:22 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>삐삐에스</managingEditor>
    <image>
      <title>빙글빙글 돌아가는 IT 人의 하루</title>
      <url>https://tistory1.daumcdn.net/tistory/5728329/attach/d222c9e80e524c73bdf8fdff0c2765a0</url>
      <link>https://vvs010.tistory.com</link>
    </image>
    <item>
      <title>물 흐르듯 사용가능한 화면이란</title>
      <link>https://vvs010.tistory.com/73</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용자 경험은 개발자가 1순위로 고려해야하는 사항이지만 그만큼 가장 어려워하는 것 중 하나이다.&lt;br /&gt;보통의 개발자는 개발자의 관점에서 생각하고 본인의 방식대로 표현한다.&lt;br /&gt;개발자의 관점에서 개발된 프로그램이라&amp;hellip;&lt;br /&gt;우리는 누구를 위한 프로그램을 만들고 있는걸까?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;우리는 사용자를 최우선으로 생각해야한다.&lt;br /&gt;물론 보안, 깔끔한 코드, 최적의 쿼리 등등 고려해야할 것은 많지만 사용자가 사용하기 어렵게 만들면 결코 그 프로그램은 성공할 수 없다.&lt;br /&gt;목으로도 날 수 없는 프로그램이라는 것이다!!&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;오늘은 어떤 화면을 개발하면서 직관적인 플로우에 대해 많은 고민을 해보게 되었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;예를 들어 어떤 상품에 가입하기 위해서는 설문을 반드시 진행해야한다고 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이전 설문 결과가 있으면 그 결과를 그대로 가져다 쓸 수도 있고, 없으면 새로 설문을 진행할 수도 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;사용자 A는 오늘 어떤 상품에 가입하기 위해 설문을 진행하려고 하는데 이때 기존 설문 결과를 활용하려고 한다.&lt;br /&gt;화면 좌측 상단에는 활용하고자 하는 설문의 직전 설문 결과가 출력되고, 화면 우측 상단에는 활용하고자 하는 설문의 결과를 출력하고 있다.&lt;br /&gt;그 화면은 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EtV1m/dJMcaiPQOIL/E9NqvtKe91AAAZ8JMjkXdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EtV1m/dJMcaiPQOIL/E9NqvtKe91AAAZ8JMjkXdk/img.png&quot; data-alt=&quot;created by Gemini&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EtV1m/dJMcaiPQOIL/E9NqvtKe91AAAZ8JMjkXdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEtV1m%2FdJMcaiPQOIL%2FE9NqvtKe91AAAZ8JMjkXdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;created by Gemini&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 화면에서는 이해할 수 없는 부분이 몇 가지 있었다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. 좌측 상단은 &amp;lsquo;직전 설문결과&amp;rsquo; 인 것 알겠어. 근데 우측 상단에 저건 그럼 뭐야? 현재 설문결과라는 건가?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;위와 같은 의문이 들었는데 코드를 뜯어보고나서야 아~ 현재 설문결과구나. 라는 걸 알았다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 나처럼 코드를 뜯어볼 수도 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;개발자인 나조차도 한번에 납득가지 않는 화면이라면 사용자에게는 굉장히 모호한 정보인 셈이다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. 기존 설문 결과를 활용하지 않고, 새로운 설문을 진행하는 경우에도 기존 설문 결과와 동일하게 문구가 출력된다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;새로운 설문 화면에서의 &amp;lsquo;직전 설문결과&amp;rsquo;에는 &amp;lsquo;기존 설문의 직전 설문결과&amp;rsquo;가 아니라 &amp;lsquo;기존 설문결과&amp;rsquo;가 출력되어야하는 것이 마땅하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이해하기 쉽도록 설문의 시간 순서를 아래와 같이 설정하겠다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;(과거)&amp;nbsp; past 1 &amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;gt; past 2 &amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;gt; new&amp;nbsp; (현재)&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;past 1은 past 2보다 이전에 진행한 설문이다. past 2는 가장 최근에 진행한 설문이다. new는 새로 진행하고자 하는 설문이다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;즉, past 2의 결과를 활용하고자 할 때는 &amp;lsquo;직전 설문결과&amp;rsquo;에 &lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;past 2의 직전 설문인&amp;nbsp;&lt;/span&gt;past 1의 결과를 가져다 쓰는 게 맞지만, new를 진행하려고 할 때는 &amp;lsquo;직전 설문결과&amp;rsquo;에 past 1이 아니라 가장 최근에 진행한 설문인 past 2의 결과를 쓰는 게 맞다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;위 2가지 문제점을 어떻게 해결하면 좋을까?&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;우선 첫 번째 의문점부터 해결해보려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;UI의 통일성과 직관성을 위해 우측 상단에도 &quot;현재 설문결과 : &quot; 라는 문구를 추가하자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYRt8t/dJMcac3b8kp/Ie9MV5fTjDcXvPKS1kD4ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYRt8t/dJMcac3b8kp/Ie9MV5fTjDcXvPKS1kD4ik/img.png&quot; data-alt=&quot;created by Gemini&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYRt8t/dJMcac3b8kp/Ie9MV5fTjDcXvPKS1kD4ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYRt8t%2FdJMcac3b8kp%2FIe9MV5fTjDcXvPKS1kD4ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;created by Gemini&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 문구를 추가하면 보다 직관적으로 정보를 이해할 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;(제미나이가 이미지를 완벽하게 만들어주지 못해서 3/5를 3/ 라고 표기했다... 이정도 오류는 이해해주길...)&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 두 번째 의문점을 해결해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 설문 정보를 활용하는 경우에는 현행대로 직전 설문결과와 현재 설문결과를 모두 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 새로운 설문을 진행하는 경우에는 아직 현재 설문결과를 알 수 없으므로 현재 설문결과는 출력되지 않고, 직전 설문결과만 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 이때 직전 설문결과는 가장 최근에 진행한 설문 결과를 출력하는 것으로 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccSFYg/dJMcacWq8TU/G2ID3aWXQfNXrpkusRAk50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccSFYg/dJMcacWq8TU/G2ID3aWXQfNXrpkusRAk50/img.png&quot; data-alt=&quot;created by Gemini&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccSFYg/dJMcacWq8TU/G2ID3aWXQfNXrpkusRAk50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccSFYg%2FdJMcacWq8TU%2FG2ID3aWXQfNXrpkusRAk50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;created by Gemini&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 더 나아가면 새로운 설문을 모두 진행하고 Submit(제출) 버튼을 눌렀을 때 '현재 진단결과'에 방금 제출한 결과를 보여주고 화면을 종료할지 여부를 물어보는 것도 괜찮을 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 UI/UX 디자이너가 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 화면 디자인에 대해 잘 알지는 못하지만 사용자의 입장에서 매끄럽지 않은 화면 구성이라면 좋은 프로그램이 아니라는 것만은 확실하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 팀에는 UI/UX를 담당하는 직원이 따로 없고 개발자들이 디자인, 백엔드 개발, 프론트엔드 개발을 모두 해야하기 때문에 더 많은 고민이 필요한 것 같다. 하나를 개발하는 데에 시간이 좀 걸리지만 다음 수정 때는 5분안에 끝낼 수 있을 정도로 깔끔하고 완벽한 프로그램을 만들기 위해 노력하고 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 UI/UX 디자이너들이 이 글을 본다면 어떤 식으로 화면을 구성하면 좋을지 같이 이야기해봐도 좋을 것 같다!&lt;/p&gt;</description>
      <category>프론트엔드/UI UX</category>
      <category>UI</category>
      <category>UI/UX</category>
      <category>UX</category>
      <category>개발</category>
      <category>디자인</category>
      <category>프론트엔드</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/73</guid>
      <comments>https://vvs010.tistory.com/73#entry73comment</comments>
      <pubDate>Mon, 23 Feb 2026 22:49:59 +0900</pubDate>
    </item>
    <item>
      <title>PAD + MOD</title>
      <link>https://vvs010.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 Oracle의 여러가지 키워드에 대해서 알아보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 유지보수 개발 요청이 들어와서 코드를 뜯어보던 중 전반적인 아키텍쳐가 이상한 것을 깨닫고 전체 구조를 뜯어보는데 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;몇날며칠을&lt;/span&gt; 썼다. 그리고 저번주에 그 근본적인 원인을 찾았는데 그 원인은 바로 &lt;u&gt;&lt;b&gt;테이블 구조&lt;/b&gt;&lt;/u&gt;였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 PK가 이상하게 설정되어 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PK는 Primary Key의 준말로 우리말로는 기본키 라고 불린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;기본키는 그 조합이 유일해야한다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이 테이블은 기본키의 조합이 유일하지 않게 설계되어 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나는 유일한 값을 만들기 위해 &lt;b&gt;일련번호 컬럼을 하나 추가&lt;/b&gt;하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 일련번호의 타입을 VARCHAR2(15)로 설정했는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;날짜(YYYYMMDD, 8) + 구분코드(_, 1) + 브랜치(지점)코드(___, 3) + 숫자,일련번호(___, 3)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 15자를 구성할 계획이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 부딪힌 벽은 마지막 일련번호였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;오라클에서 일련번호를 어떻게 설정하지?&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 테이블에서는 일련번호를 어떻게 만들어내고 있는지를 살펴보니 LPAD와 MOD라는 키워드를 쓰고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 키워드를 이번에 처음 보고 공부하게 되어 이 글을 보는 독자분들께도 소개시켜드리고자 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Lpad&lt;/b&gt;는 Left + Pad, &lt;u&gt;문자열의 왼쪽을 지정된 길이까지 특정 문자 세트로 채우는 표현식&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 키워드는 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;lpad(Dimension, length, &quot;characters to pad&quot;) 이렇게 쓰는데, 아래 예시를 보며 살펴보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;Case #1&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770032909420&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LPAD('hellomyfriend', 15, '*')
FROM DUAL&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;위와 같은 표현식이 있다고 가정해보자. 이 표현식을 실행해보겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brG5cr/dJMcafk9TEk/ZolgqMSQfrrZnW8oTwIRV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brG5cr/dJMcafk9TEk/ZolgqMSQfrrZnW8oTwIRV0/img.png&quot; data-alt=&quot;컴파일러 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brG5cr/dJMcafk9TEk/ZolgqMSQfrrZnW8oTwIRV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrG5cr%2FdJMcafk9TEk%2FZolgqMSQfrrZnW8oTwIRV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;211&quot; height=&quot;167&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일러 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보면 hellomyfriend 왼쪽에 *이 2개 붙었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LPAD를 통해 &lt;b&gt;hellomyfriend 13자&lt;/b&gt; 왼쪽에 &lt;b&gt;padding characters '*'를 2개 추가&lt;/b&gt;하여 &lt;b&gt;15자&lt;/b&gt;를 만든 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;Case #2&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770033557498&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LPAD('hellomyfriend', 10, '*')
FROM DUAL&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 Dimension보다 length가 더 짧다. 이런 경우는 어떻게 나올까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RGWin/dJMcagRUHSJ/OyJIb76xxFlzsk03OmNsr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RGWin/dJMcagRUHSJ/OyJIb76xxFlzsk03OmNsr0/img.png&quot; data-alt=&quot;컴파일러 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RGWin/dJMcagRUHSJ/OyJIb76xxFlzsk03OmNsr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRGWin%2FdJMcagRUHSJ%2FOyJIb76xxFlzsk03OmNsr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;231&quot; height=&quot;155&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일러 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 오른쪽 끝에 end가 줄었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LPAD를 쓸 때 표현식보다 짧은 길이를 지정할 경우, 왼쪽을 기준으로 해당 길이만큼 자른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LPAD는 왼쪽에 패딩을 채우는 표현식이라면, RPAD는 Right + Pad, 오른쪽에 패딩을 채우는 표현식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 케이스의 반대라고 생각하면 된다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 &lt;b&gt;MOD&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;Mod는 &lt;u&gt;나누기 결과 나머지를 반환하는 수학 함수&lt;/u&gt;이다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;이 함수를 사용하는 법과 간단한 사용 예시를 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수는 2개의 매개변수를 사용한다. &lt;b&gt;Mod(arg1, arg2)&lt;/b&gt; 는 arg1 % arg2의 값을 리턴한다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 보면서 이 함수를 익혀보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Case #1&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770125224972&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT MOD(1234,1000)
FROM DUAL;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리를 실행시켜보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjQlrM/dJMcad1TM9W/suqXSCA8W740bmfeXOJWQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjQlrM/dJMcad1TM9W/suqXSCA8W740bmfeXOJWQ1/img.png&quot; data-alt=&quot;컴파일러 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjQlrM/dJMcad1TM9W/suqXSCA8W740bmfeXOJWQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjQlrM%2FdJMcad1TM9W%2FsuqXSCA8W740bmfeXOJWQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;183&quot; height=&quot;157&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일러 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1234 라는 숫자를 1000으로 나눈 나머지를 리턴하는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Case #2&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770125383757&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT MOD('1234', 1000)
FROM DUAL;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 위와 같이 문자열을 arg1에 두면 어떻게 될까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sRApg/dJMb99LZMig/cq6D9kNneAsv6csTg7aUDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sRApg/dJMb99LZMig/cq6D9kNneAsv6csTg7aUDK/img.png&quot; data-alt=&quot;컴파일러 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sRApg/dJMb99LZMig/cq6D9kNneAsv6csTg7aUDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsRApg%2FdJMb99LZMig%2Fcq6D9kNneAsv6csTg7aUDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;183&quot; height=&quot;146&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일러 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 매개변수를 문자열로 설정했음에도 &lt;span style=&quot;color: #009a87;&quot;&gt;Case #1&lt;/span&gt;과 동일한 결과가 도출되는 것을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이건 '1234'가 형식상으로는 문자열처럼 보이지만 내용은 숫자라 가능한 결과 아닐까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 예시를 통해 더 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Case #3&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770125629378&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT MOD('ABCD', 1000)
FROM DUAL;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 만약 위처럼 첫 번째 매개변수를 알파벳 문자열로 설정하면 어떻게 될까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2yjUC/dJMb99LZMlo/FZkOSlOn3iL5KuynhbLkX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2yjUC/dJMb99LZMlo/FZkOSlOn3iL5KuynhbLkX1/img.png&quot; data-alt=&quot;컴파일러 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2yjUC/dJMb99LZMlo/FZkOSlOn3iL5KuynhbLkX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2yjUC%2FdJMb99LZMlo%2FFZkOSlOn3iL5KuynhbLkX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;542&quot; height=&quot;149&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일러 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 A가 문자열이기 때문에 숫자로 바꿀 수 없다는 에러가 뜬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, MOD 함수의 인수는 숫자만 입력 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2458&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8Jpae/dJMcacIK2S0/LkO0EgsPQxUOQCD12mDyR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8Jpae/dJMcacIK2S0/LkO0EgsPQxUOQCD12mDyR1/img.png&quot; data-alt=&quot;Oracle 공식 문서&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8Jpae/dJMcacIK2S0/LkO0EgsPQxUOQCD12mDyR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8Jpae%2FdJMcacIK2S0%2FLkO0EgsPQxUOQCD12mDyR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2458&quot; height=&quot;274&quot; data-origin-width=&quot;2458&quot; data-origin-height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Oracle 공식 문서&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나는 이 일련번호를 다음과 같이 설정했다.&lt;/p&gt;
&lt;pre id=&quot;code_1770126024234&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TO_CHAR(SYSDATE,'YYYYMMDD')
|| #DIS_CD#
|| #BR_CD#
|| LPAD(MOD(ROWNUM, 1000), 3, '0')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 절을 SELECT 인자로 넣어 실행하면 아래와 같이 결과가 도출된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmH4wF/dJMcabbY5MJ/K6jN76Pt5Fi0ek7nRCuqX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmH4wF/dJMcabbY5MJ/K6jN76Pt5Fi0ek7nRCuqX1/img.png&quot; data-alt=&quot;컴파일러 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmH4wF/dJMcabbY5MJ/K6jN76Pt5Fi0ek7nRCuqX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmH4wF%2FdJMcabbY5MJ%2FK6jN76Pt5Fi0ek7nRCuqX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;260&quot; height=&quot;158&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일러 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 INSERT 문 안에 위 절을 넣고 실행하면 ROWNUM에서 에러가 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ROWNUM은 SELECT 문에만 둬야한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 최종적으로는 아래와 같이 쿼리를 구성했다.&lt;/p&gt;
&lt;pre id=&quot;code_1770126894871&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT TABLE1
    (COL1,
     COL2,
     COL3,
     ...,
     SRNO)
VALUES (#COL1#,
        #COL2#,
        #COL3#,
        ...,
        TO_CHAR(SYSDATE, 'YYYYMMDD')
         || #DIS_CD#
         || #BR_CD#
         || LPAD(MOD(NVL(MAX(SRNO),0),1000)+1, 3, '0');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 쿼리를 구성했더니 정상적으로 일련번호가 채번되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일련번호(PK)를 채번하는 방법은 여러가지가 있겠지만 이 방법도 고려해보면 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론 SYSDATE, DIS_CD, BR_CD가 겹칠 일이 1000번 이상 발생하지 않는다는 전제하에 이 방법을 고려해보길 바란다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 게시글에는 쓰고 싶은 내용이 많아 좀 길어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 맡고 있는 다른 시스템에서는 시퀀스(Sequence)를 쓰고 있어 이렇게 어렵게 일련번호를 채번할 필요가 없는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 작업 중인 이 시스템은 시퀀스를 쓰고 싶지 않아 직접 일련번호를 하나하나 + 1 해가며 갱신해줘야하는 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 복잡한 문제를 한번에 해결해줄 시퀀스는 다음에 공부해서 가져오겠다!&lt;/p&gt;</description>
      <category>SQL</category>
      <category>oracle</category>
      <category>SQL</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/72</guid>
      <comments>https://vvs010.tistory.com/72#entry72comment</comments>
      <pubDate>Tue, 3 Feb 2026 23:01:36 +0900</pubDate>
    </item>
    <item>
      <title>Good Code, Clean Code</title>
      <link>https://vvs010.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 클린 코드라는 책을 읽기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영어 공부도 할 겸 원서로 읽느라 읽는데 시간이 좀 걸리지만 굉장히 유익한 책이라는 생각이 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yKOlY/dJMcajncv1W/2OdU2EZxJm8GZVxm7Lo950/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yKOlY/dJMcajncv1W/2OdU2EZxJm8GZVxm7Lo950/img.jpg&quot; data-alt=&quot;한국어로 번역된 책도 있으니 관심이 있다면 꼭 읽어보는 것을 추천한다!!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yKOlY/dJMcajncv1W/2OdU2EZxJm8GZVxm7Lo950/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyKOlY%2FdJMcajncv1W%2F2OdU2EZxJm8GZVxm7Lo950%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;229&quot; height=&quot;304&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한국어로 번역된 책도 있으니 관심이 있다면 꼭 읽어보는 것을 추천한다!!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 본격적으로 개발을 하면서 꽤 많은 코드를 쓰고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;매번 어떻게 코드를 쓰는 것이 좋을지&lt;/b&gt;&lt;/u&gt; 고민하는 데에 많은 시간과 에너지를 들이고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서! 좋은 코드란 뭔가? 를 알아내기 위해 열심히 책을 읽고 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책에는 굉장히 많은 위인(?)들이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중에 몇가지 내 마음을 울린 글을 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 잊혀져가는 코드의 중요성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책의 초반에는 요즘 개발의 현실에 대해 꼬집는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 코드가 아닌 모듈과 요구사항에 대한 중요도가 더 강조되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자라면 아는 유명한 짤을 보면 무슨 말인지 단박에 알아차릴 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;1536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPEDOw/dJMcacaACY2/rYjy8iZNYxWsi5QXLoX92K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPEDOw/dJMcacaACY2/rYjy8iZNYxWsi5QXLoX92K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPEDOw/dJMcacaACY2/rYjy8iZNYxWsi5QXLoX92K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPEDOw%2FdJMcacaACY2%2FrYjy8iZNYxWsi5QXLoX92K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;448&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;1536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요구사항만 맞추면 코드가 어떻게 짜여있든 중요하지 않다고 여기는 사람들이 굉장히 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이 저자는 이렇게 말한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;Remember that code is really the language in which we ultimately express the requirements.&lt;br /&gt;(코드는 우리가 궁극적으로 요구사항을 표현하는 언어라는 점을 기억해라.)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 아무리 요구사항을 충족하는 언어를 새롭게 만들고 도구를 만들어도,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'코드'는 피할수없는 대전제라는 말을 하고 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 엉망이 되어가는 코드, Bad Code&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자들은 기획자가 정해놓은 deadline을 맞추기 위해 좋은 코드에 대한 고민없이 목으로라도 돌아가는 코드를 짜낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 이 저자는 Professionalism, Responsibility에 대해 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기획자가 열정을 가지고 스케줄과 요구사항을 지켜내려고 하는 것은 그들의 일이 그것이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 기획자는 자신의 일을 하는 것일 뿐이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 개발자인 우리는 그저 따라야만 하는 것일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니다. 기획자가 그들의 일을 열정적으로 하듯이 우리도 우리의 일을 해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;우리는 코드를 지켜야한다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;It is unprofessional for programmers to bend to the will of managers who don't understand the risks of making messes.&lt;br /&gt;&lt;/span&gt;(엉망인 코드를 만드는 것의 위험성을 이해하지 않으려하는 기획자들의 의지에 꺾이는 개발자는 프로페셔널하지 않다.)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 클린 코드란?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;자, 그래서 클린 코드가 뭔데?&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굉장히 많은 사람들의 의견이 제시되는데 거의 대부분 비슷한 결론에 이른다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;클린 코드 = 읽기 쉬운 코드&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막에 나오는 말에 신선한 충격을 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;We Are Authors.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 작가다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작가라는 건 우리가 쓴 글을 읽는 '독자'가 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 작가들에게는 독자들과 잘 소통할 책임이 있기 때문에 읽기 쉬운 코드를 써야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;If you want to go fast, if you want to get done quickly, if you want your code to be easy to write, make it easy to read.&lt;br /&gt;&lt;/span&gt;(빨리 가고 싶다면, 빨리 끝내고 싶다면, 코드를 쉽게 쓰고 싶다면 읽기 쉽게 만들어라.)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전부터 읽어보고 싶었던 책이었는데 드디어 읽어볼 수 있게 되어 너무 좋다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항상 시간이 없다는 핑계로 미뤘지만 이제 진짜 개발자로서의 커리어를 시작한 이상 더 나은 시스템을 만들기 위해 끊임없이 노력해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 모르는 것도 너무나 많고 실수도 많이 하지만 이런 지식들을 쌓아서 느려도 멈추지 않는 사람이 되고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤에 남은 챕터들도 얼른 읽고 게시글로 공유해보겠다!&lt;/p&gt;</description>
      <category>개발 공부</category>
      <category>개발</category>
      <category>코드</category>
      <category>클린코드</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/71</guid>
      <comments>https://vvs010.tistory.com/71#entry71comment</comments>
      <pubDate>Tue, 16 Dec 2025 23:39:13 +0900</pubDate>
    </item>
    <item>
      <title>빈 그릇 테이블, DUAL</title>
      <link>https://vvs010.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 DUAL이라는 테이블에 대해 알아보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DUAL은 나에게 그리 익숙한 문법이 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 처음에는 부끄럽지만 DUAL이라는 테이블이 도대체 어떤 테이블인지 한참 찾았었다........&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도대체 얼마의 시간을 쓴건지...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나!!! 그런 시간이 있기에 배움의 가치를 더 크게 느낀다고 생각하기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;럭키비키 마인드로~★☆&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분은 그 시간을 아꼈으면 하는 마음에서 오늘의 주제는 DUAL로 잡아봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쿼리를 쓰다보면 FROM절 없이 SELECT만 쓰고 싶을 때가 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들면 그냥 파라미터 값을 그대로 리턴하는 SELECT 문 같은거!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 때 유용하게 쓸 수 있는 것이 DUAL 테이블이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;DUAL&lt;/b&gt;은 쉽게 말하면 1x1 크기의 가상 테이블이라고 볼 수 있다.&lt;br /&gt;즉, &lt;u&gt;단 하나의 행과 단 하나의 컬럼&lt;/u&gt;으로 구성되어있다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DUAL은 다양하게 활용이 가능한데 오늘은 3가지 정도를 알아보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 상수 값 및 계산 결과 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 예시를 들었던 부분이 이 케이스에 해당된다고 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1765809804737&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 1+1
    , 'HELLO'
  FROM DUAL&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리를 실행하면 아래와 같이 나온다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu4EEn/dJMcaaDPYrv/jK6qUkHuaiiTTlj1BVgTR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu4EEn/dJMcaaDPYrv/jK6qUkHuaiiTTlj1BVgTR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu4EEn/dJMcaaDPYrv/jK6qUkHuaiiTTlj1BVgTR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu4EEn%2FdJMcaaDPYrv%2FjK6qUkHuaiiTTlj1BVgTR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;338&quot; height=&quot;191&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계산 결과와 상수 값이 잘 출력되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 주로 파라미터값을 그대로 조회할 필요가 있을 때 주로 쓴다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 파라미터로 &lt;u&gt;&lt;b&gt;서브쿼리&lt;/b&gt;&lt;/u&gt;를 쓰는 경우에 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직원 테이블이 있다고 가정해보자.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 68px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;&lt;b&gt;EMP_ID&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;&lt;b&gt;EMP_NAME&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;&lt;b&gt;EMP_AGE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;&lt;b&gt;DEPT&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;&lt;b&gt;SALARY&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;1001&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;KEVIN&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;24&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;ACCOUNTING&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;4300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;1002&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;EMILY&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;27&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;IT&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;5100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;1003&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;JOHN&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;30&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;MARKETING&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px; text-align: left;&quot;&gt;5800&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 여기서 &lt;b&gt;연봉이 #SALARY#보다 많은 직원 아이디 리스트를 뽑아내는 쿼리&lt;/b&gt;를 쓰려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때 WHERE SALARY &amp;gt; #SALARY# 라고 쓸 수도 있지만 &lt;u&gt;DUAL 서브쿼리도 사용 가능&lt;/u&gt;하다!&lt;/p&gt;
&lt;pre id=&quot;code_1765810343616&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT EMP_ID
  FROM EMP
 WHERE SALARY &amp;gt; (SELECT #SALARY#
                   FROM DUAL);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#SALARY#에 5500을 넣고 위 쿼리를 수행하면 아래처럼 결과가 나온다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;266&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DdSmk/dJMcagcZYyB/MxTmTbkB7pzDxserBs53Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DdSmk/dJMcagcZYyB/MxTmTbkB7pzDxserBs53Z0/img.png&quot; data-alt=&quot;연봉이 5500이 넘는 사람은 JOHN밖에 없다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DdSmk/dJMcagcZYyB/MxTmTbkB7pzDxserBs53Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDdSmk%2FdJMcagcZYyB%2FMxTmTbkB7pzDxserBs53Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;173&quot; height=&quot;183&quot; data-origin-width=&quot;266&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연봉이 5500이 넘는 사람은 JOHN밖에 없다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 시스템 정보 조회&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번과 일맥상통한 케이스이긴 하지만 시스템 함수 결과를 조회할 때 쓸 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1765810797458&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT SYSDATE
  FROM DUAL;
  
SELECT USER
  FROM DUAL;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 함수 테스트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TO_CHAR, TO_DATE 같은 내장 함수나 PL/SQL할 때 주로 쓰는 Function을 테스트할 때 쓰기 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가끔 코딩 테스트를 볼 때 함수 사용법이 잘 기억이 나지 않을 때 써도 좋은 방법인 것 같다!&lt;/p&gt;
&lt;pre id=&quot;code_1765810935107&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ROUND(3.14159)
  FROM DUAL;
  
SELECT SUBSTR('OracleDB', 1, 4)
  FROM DUAL;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 오라클의 빈 그릇 테이블인 DUAL에 대해 알아봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쓰다보니 꽤 유용하고 많이 쓰게 되어 꼭 소개하고 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나같은 주니어 개발자는 선배님들이 쓰신 쿼리를 많이 읽어보는게 참 중요한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스스로 의문점도 가져보고 새로운 개념도 배우고!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무를 하면 할수록 부족함도 많이 느껴지지만 그만큼 배울 게 많다는 데에 매일이 설렌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하루하루 꾸준히 발전해나가다보면 나중에 엄청난 핵심 코드 한 줄로 문제를 해결해버리는 엄청난 개발자가 될 수도 있지 않을까?&lt;/p&gt;</description>
      <category>SQL</category>
      <category>dual</category>
      <category>SQL</category>
      <category>가상테이블</category>
      <category>서브쿼리</category>
      <category>오라클</category>
      <category>쿼리</category>
      <category>테이블</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/70</guid>
      <comments>https://vvs010.tistory.com/70#entry70comment</comments>
      <pubDate>Tue, 16 Dec 2025 00:12:50 +0900</pubDate>
    </item>
    <item>
      <title>두 테이블을 비교하여 값 갱신하기, MERGE 사용법</title>
      <link>https://vvs010.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 새로운 개념을 만나지 못해서 블로그를 못쓰고 있었는데 오랜만에 새로운 먹잇감을 발견했다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 MERGE 사용법에 대해 알아보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 아래와 같은 코드를 보게 되었다.&lt;/p&gt;
&lt;pre id=&quot;code_1765378688940&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MERGE INTO TABLE T
USING
	(SELECT 
    	#COL1# COL1,
    	#COL2# COL2,
        #COL3# COL3,
        #COL4# COL4
     FROM DUAL
    ) S
ON (
	T.COL1 = S.COL1
    AND T.COL2 = S.COL2
    AND T.COL3 = S.COL3
   )
WHEN MATCHED THEN
	UPDATE SET
    	T.COL1 = S.COL1,
        T.COL2 = S.COL2,
        T.COL3 = S.COL3,
        T.COL4 = S.COL4
WHEN NOT MATCHED THEN
	INSERT
    	(
        COL1,
        COL2,
        COL3,
        COL4
        )
     VALUES (
     	S.COL1,
        S.COL2,
        S.COL3,
        S.COL4
     )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MERGE 키워드는 나에게 생소해서 도대체 어떻게 해석을 해야하는건지 막막했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 MERGE문이란 뭔지 먼저 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MERGE문은 &lt;b&gt;테이블에 데이터를 삽입(INSERT)하거나 갱신(UPDATE)하는 작업을 수행&lt;/b&gt;할 수 있게 해주는 구문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 &lt;u&gt;원본 테이블(Target Table)과 소스 데이터(Source Data)를 비교&lt;/u&gt;하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터가 이미 존재하면 갱신(UPDATE)&lt;/b&gt;하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;존재하지 않으면 새로 삽입(INSERT)&lt;/b&gt;하는 형식으로 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 MERGE 문의 사용목적은 알았으니 쿼리를 좀 뜯어보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. MERGE INTO 뒤에 나오는 TABLE T는 대상 테이블(Target Table)이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, TABLE T는 '병합 대상'으로 이 테이블의 데이터가 변경된다고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. USING 뒤에 나오는 SELECT 문은 소스 데이터(Source Data)이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대상 테이블에 이 소스 데이터를 적용하게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. ON 절은 대상 테이블과 소스 데이터의 매칭 조건이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분이 MERGE 문의 핵심이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말해 대상 테이블의 행과 소스 데이터의 행을 연결하는 조인 조건이라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. WHEN MATCHED THEN ~ 절은 매칭되었을 때 (데이터가 있을 때) 실행되는 구문이다.&lt;/b&gt;&lt;br /&gt;ON 절의 결과가 참일 때 THEN 이하 구문이 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구문은 생략불가하므로 MERGE 문에 반드시 써야한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 이 구문에는 UPDATE SET이나 DELETE WHERE 문을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. WHEN NOT MATCHED THEN ~ 절은 매칭되지 않았을 때 (데이터가 없을 때) 실행되는 구문이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ON 절의 결과가 거짓일 때 THEN 이하 구문이 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구문은 WHEN MATCHED THEN 절과 달리 생략 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 이 구문에는 INSERT INTO 만 사용 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 MERGE INTO 구문을 사용하여 쿼리를 하나 짜보자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;동일 테이블에 대해 기준월(BASE_YM)이 당월인 데이터와 기준월이 익월인 데이터를 비교하여&lt;br /&gt;익월 데이터가 있으면 그대로 두고&lt;br /&gt;익월 데이터가 없으면 INSERT하는 형식으로 쿼리를 짜볼 것이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 쿼리를 구성하면 좋을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 대상 테이블과 소스 데이터는 기준월만 다른 동일 테이블이어야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 ON 절에는 기준월을 제외한 COL1, COL2가 같아야한다는 조건이 필요하다고 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 아래와 같이 쿼리가 나오게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1765380724481&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MERGE INTO TESTTABLE T
USING
    (
        -- 1. 소스 데이터 (당월 데이터) 조회
        SELECT
            COL1,
            COL2,
            TO_CHAR(ADD_MONTHS(SYSDATE, 1), 'YYYYMM') AS NEXT_BASE_YM 
        FROM
            TESTTABLE
        WHERE
            BASE_YM = TO_CHAR(SYSDATE, 'YYYYMM')
    ) S
ON (
    -- 2. 매칭 조건: 익월 테이블에서 COL1,COL2와 익월 BASE_YM이 일치하는지 확인
    T.COL1 = S.COL1
    AND T.COL2 = S.COL2
    AND T.BASE_YM = S.NEXT_BASE_YM
)
WHEN MATCHED THEN
    -- 3. 매칭됨 (익월 데이터가 이미 존재함): 아무 작업도 하지 않음
    UPDATE SET
        T.COL1 = S.COL1 -- 의미 없는 UPDATE (자기 자신으로 갱신)
    WHERE 1 = 0                  -- **WHERE 1 = 0을 사용하여 실제 갱신 방지**
WHEN NOT MATCHED THEN
    -- 4. 매칭되지 않음 (익월 데이터가 존재하지 않음): INSERT 실행
    INSERT
        (BASE_YM, COL1, COL2)
    VALUES
        (S.NEXT_BASE_YM, S.COL1, S.COL2)
;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MERGE 구문을 사용하면 복잡한 요구사항이 와도 위처럼 아주 쉽게 쿼리를 완성할 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 이렇게 두 개의 테이블을 비교해서 값을 변형해야할 일이 있다면 MERGE 구문도 고려해보면 좋겠다.&lt;/p&gt;</description>
      <category>SQL</category>
      <category>insert</category>
      <category>merge</category>
      <category>oracle</category>
      <category>SQL</category>
      <category>Update</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/69</guid>
      <comments>https://vvs010.tistory.com/69#entry69comment</comments>
      <pubDate>Thu, 11 Dec 2025 00:37:41 +0900</pubDate>
    </item>
    <item>
      <title>기본중의 기본, 문자열 비교</title>
      <link>https://vvs010.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 아주 기초적이지만 그렇기에 많이들 놓치는 부분에 대해 알아보려고 한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 있었던 일화를 먼저 이야기하고 시작하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 아래와 같이 코드를 짜고 있었다.&lt;/p&gt;
&lt;pre id=&quot;code_1764681129974&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (StringUtils.equals(&quot;Y&quot;, request.getField(&quot;YN&quot;)) {
	~~~~~
}

...

if (request.getField(&quot;USER_INFO&quot;) == &quot;13&quot;) {
	~~~~~
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 코드를 작성하다보니 &quot;YN&quot;값이 NULL인 상황이 있을 수 있다는 것을 파악하고는 책임자분께 여쭤봤다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;과장님, 만약에 request에 YN이라는 필드가 없으면&lt;br /&gt;&lt;b&gt;StringUtils.equals(&quot;Y&quot;, request.getField(&quot;YN&quot;))&lt;/b&gt; 은 &lt;u&gt;false&lt;/u&gt;가 되나요? 아니면 이 코드에서 &lt;u&gt;에러&lt;/u&gt;가 터지나요?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 질문에 대한 답은 &lt;i&gt;&lt;b&gt;false가 된다.&lt;/b&gt;&lt;/i&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 답을 주시면서 내 코드를 보시더니&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;대리님, 문자열에는 == 쓰면 안돼요. 만약에 USER_INFO 값이 NULL이면 저기서 에러날거에요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 하셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 순간 &lt;i&gt;&lt;b&gt;아 맞다! 문자열에는 == 비교를 안쓰지!&lt;/b&gt;&lt;/i&gt; 라는 생각이 스치면서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;근데 왜 못 쓰더라?&lt;/b&gt;&lt;/i&gt; 라는 생각이 동시에 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 오늘의 블로그 주제는 &lt;b&gt;'자바에서의 문자열 비교'&lt;/b&gt; 가 되었다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 문자열에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JAVA에서의 문자열은 String 클래스를 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 생각하자면 String 클래스가 문자열 타입이라고 생각하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1764682269919&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String str = &quot;문자열&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 String class를 살짝만 뜯어보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;String 클래스는 &lt;b&gt;java.lang 패키지에 속한 클래스&lt;/b&gt;인데 java.lang은 자바에서 기본으로 import되기 때문에 따로 선언할 필요는 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 모든 클래스가 그렇듯이 String 클래스 역시 java.lang.Object 클래스를 상속받고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oracle에서 제공하는 문서를 보면 String 클래스는 문자열을 나타낸다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 쓰이는 &quot;abc&quot;와 같은 문자열은 모두 이 &lt;u&gt;String 클래스의 인스턴스로 구현&lt;/u&gt;되어 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서는 &lt;b&gt;문자열을 연결하는 연산자&lt;/b&gt;와 &lt;b&gt;문자열이 아닌 어떤 객체를 문자열 객체로 바꿔주는 연산자&lt;/b&gt;를 제공하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;문자열을 연결하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 간단하게 &lt;u&gt;+ 연산자를 이용&lt;/u&gt;할 수도 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; &lt;u&gt;StringBuilder(혹은 StringBuffer) 클래스의 append method를 이용&lt;/u&gt;할수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;문자열 변환 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; Object 클래스에 정의된 &lt;u&gt;toString method를 이용&lt;/u&gt;하여 구현되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 마지막으로 알아둬야할 점은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;String class의 생성자나 method에 NULL값이 전달되면 NullPointerException이 터진다&lt;/u&gt;는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 String '객체' 를 비교하기 위해서는 어떻게 해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차원적으로 생각해보면 == 으로 비교하면 될 것만 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 만약 아래 코드를 실행시켜보면 어떻게 될까?&lt;/p&gt;
&lt;pre id=&quot;code_1764685552537&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String str1 = new String(&quot;abc&quot;);
String str2 = new String(&quot;abc&quot;);

// case 1
if (str1 == &quot;abc&quot;) {
	System.out.println(&quot;1: 같음&quot;);
} else {
	System.out.println(&quot;2: 다름&quot;);
}

// case 2
if (str1 == str2) {
	System.out.println(&quot;1: 같음&quot;);
} else {
	System.out.println(&quot;2: 다름&quot;);
}

// case 3
if (str1.equals(str2)) {
	System.out.println(&quot;1: 같음&quot;);
} else {
	System.out.println(&quot;2: 다름&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 case 1을 실행시켜보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 &lt;u&gt;&lt;b&gt;2: 다름&lt;/b&gt;&lt;/u&gt; 이 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;abc랑 abc는 두 눈을 씻고 쳐다봐도 같은 문자열인데 왜 다름이 출력되는걸까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 다음으로 넘어가서 case 2를 실행시켜보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 또 &lt;u&gt;&lt;b&gt;2: 다름&lt;/b&gt;&lt;/u&gt; 이 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;abc랑 abc가 다르면 도대체 뭐가 같은 문자열이라는 거냐며 화가 잔뜩 날 수 있다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 case 3을 실행해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드!디!어!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;1: 같음&lt;/b&gt;&lt;/u&gt; 이 출력되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭘까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 == 은 안되고 equals는 되는걸까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유는 비교 대상에 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;str1&lt;/b&gt;과 &lt;b&gt;str2&lt;/b&gt;는 각각 하나의 '객체'이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;같은 내용을 가진 서로 다른 객체&lt;/b&gt;라는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각자의 집에 같은 책을 가지고 있는 상황이라고 이해하면 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;==&lt;/b&gt; 은 &lt;b&gt;참조를 비교&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;==&lt;/b&gt; 은 &lt;b&gt;주소를 비교&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;==&lt;/b&gt; 은 &lt;b&gt;같은 객체인지를 비교&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;equals&lt;/b&gt;는 &lt;b&gt;객체 안 내용이 같은 내용인지를 비교&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 차이점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;str1과 str2 집이 같은 집인가?&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;False&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;str1과 str2 집에 있는 책이 같은 책인가?&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;맞다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;True&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3298&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PjQHm/dJMb99SoNG2/msqYFvliiczjskjuLurwK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PjQHm/dJMb99SoNG2/msqYFvliiczjskjuLurwK1/img.png&quot; data-alt=&quot;출처: Oracle&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PjQHm/dJMb99SoNG2/msqYFvliiczjskjuLurwK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPjQHm%2FdJMb99SoNG2%2FmsqYFvliiczjskjuLurwK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3298&quot; height=&quot;668&quot; data-origin-width=&quot;3298&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: Oracle&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진은 Oracle에서 제공하는 String class 정의서의 method 설명 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서 내용도 정리가 잘 되어있어서 공유한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 문자열 비교 방법에 대해 알아봤다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다들 대충 알고있는 개념이었겠지만 정확히 짚고 넘어가는 계기가 되었으면 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옛날같았으면 문자열 비교에 == 쓰면 바로 호출이었다던데....&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분들은 나와 같은 실수를 하지 않길 바라면서 오늘 글은 여기서 마무리 짓겠다!&lt;/p&gt;</description>
      <category>백엔드/Java</category>
      <category>Java</category>
      <category>문자열</category>
      <category>비교</category>
      <category>자바</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/68</guid>
      <comments>https://vvs010.tistory.com/68#entry68comment</comments>
      <pubDate>Wed, 3 Dec 2025 00:03:50 +0900</pubDate>
    </item>
    <item>
      <title>숨길 땐 알고 숨기자!</title>
      <link>https://vvs010.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 데이터베이스에 다양한 정보를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이디와 비밀번호, 이름, 전화번호, 주소, 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 이름, 전화번호, 주소와 같은 개인정보나 비밀번호와 같이 알려지면 안되는 정보는 데이터베이스에 그대로 저장해서는 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 업비트가 대규모 해킹되는 일이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도&amp;nbsp;너무나 많은 해킹 사건이 일어나고 있고 우리는 이걸 막을 원천적으로 막을 힘이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;우리 내부로 들어와도, 우리의 정보를 털어가도 알아볼 수 없게 만들자!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 이번 게시물의 주제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 내가 종사하고 있는 금융권에만 해당되는 일이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학생들이 개인 프로젝트로 만드는 수많은 서비스들에도 해당되는 이야기이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숨겨야하는 정보는 최대한 완벽하게 숨기는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 은근히 많은 사람이 모르는 상식을 하나 짚고 넘어가자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'이름'은 숨겨야하는 정보일까 아닐까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정답은....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숨겨야하는 정보이다!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;(여기서 이름은 당연히 실명을 말하는 것이다... 닉네임은 뭐 숨기든 보여주든 노상관...)&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'이름'도 개인정보이기 때문에 함부로 드러나서는 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 상식으로 꼭 알고 넘어가자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호화 알고리즘의 대략적인 구분을 먼저 파악하고 시작하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;746&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NF3RH/dJMcadUJF9L/kifslX5ulJ5ff4y6Hgvbm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NF3RH/dJMcadUJF9L/kifslX5ulJ5ff4y6Hgvbm0/img.png&quot; data-alt=&quot;출처: 건기원 정보처리기사 실기 수제비 2023&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NF3RH/dJMcadUJF9L/kifslX5ulJ5ff4y6Hgvbm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNF3RH%2FdJMcadUJF9L%2FkifslX5ulJ5ff4y6Hgvbm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1636&quot; height=&quot;746&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;746&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: 건기원 정보처리기사 실기 수제비 2023&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호 알고리즘의 대분류 중 &lt;b&gt;양방향 방식&lt;/b&gt;에 대해 먼저 살펴보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양방향은 말 그대로 평문을 암호문으로 바꾸고 그 암호문을 다시 평문으로 바꿀 수 있음을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양방향 방식에는 &lt;b&gt;대칭 키 암호 방식&lt;/b&gt;과 &lt;b&gt;비대칭 키 암호방식(= 공개키 암호 방식)&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대칭 키 암호방식은 &lt;u&gt;&lt;b&gt;암호화와 복호화에 같은 키를 사용하는 방식&lt;/b&gt;&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비밀키를 사용하는데 이를 전달하기 위한 키 교환이 필요하고, 암호화 및 복호화의 속도가 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대칭 키 암호 방식은 블록 암호 방식과 스트림 암호 방식으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;블록 암호 방식&lt;/b&gt;은 긴 평문을 암호화하기 위해 고정 길이의 블록을 암호화하는 블록 암호 알고리즘을 반복하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 예로 DES, AES가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DES&lt;/b&gt;는 56bit 키를 이용하고 64bit의 평문 블록을 64bit의 암호문 블록으로 만드는 미국표준 암호화 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AES&lt;/b&gt;는 DES의 고급 버전이라고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스트림 암호 방식&lt;/b&gt;은 아주 긴 주기의 난수열을 발생시켜 평문과 더불어 암호문을 생성하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비대칭 키 암호 방식은 &lt;u&gt;&lt;b&gt;암호화와 복호화에 서로 다른 키를 사용하는 방식&lt;/b&gt;&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공개키&lt;/b&gt;와 &lt;b&gt;개인키(사설키)&lt;/b&gt;가 존재하는데, 공개키는 누구나 알 수 있지만 개인 키는 키의 소유자만이 알 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개키로 암호화된 메시지는 반드시 개인 키로 복호화해야한다고 생각하면 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 대칭 키 암호 방식에 비해 속도가 느리다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비대칭 키 암호 방식에는 RSA, DH(디피-헬만)이 대표적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RSA&lt;/b&gt;는 소인수분해의 어려움을 이용한 방식으로 현재 비대칭 키 암호방식 중에서 가장 널리 쓰이고 있는 방식이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디피-헬만&lt;/b&gt;은 두 사람이 암호화되지 않은 통신망을 통해 공통의 비밀키를 공유할 수 있도록 하는 키 교환 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 간단하게 암호화 알고리즘의 종류에 대해 간략하게 알아봤다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금융권에는 수많은 개인정보가 있기 때문에 이것을 암호화하여 보관하는 것은 아주 기본적인 역량이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 데이터베이스에서 SELECT 문을 실행해도 고객의 개인정보를 함부로 보지 못하게 만드는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말했듯이 비금융권에서도 보안은 매우 중요한 부분이니 이번 게시글을 참고하여 더 자세히 공부해보면 좋을 듯하다!&lt;/p&gt;</description>
      <category>개발 공부</category>
      <category>공개키</category>
      <category>대칭키</category>
      <category>보안</category>
      <category>복호화</category>
      <category>암호알고리즘</category>
      <category>암호화</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/67</guid>
      <comments>https://vvs010.tistory.com/67#entry67comment</comments>
      <pubDate>Mon, 1 Dec 2025 23:54:19 +0900</pubDate>
    </item>
    <item>
      <title>코드 관리</title>
      <link>https://vvs010.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도 미미하지만 중대한 실수를 저질렀다!!!!!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘의 실수 주제는 '&lt;b&gt;코드 관리&lt;/b&gt;' 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 말하는 코드 관리는 SVN, Git과 같은 형상 관리 도구(버전 관리 시스템)에 관한 이야기가 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대학교 소프트웨어공학 수업에서 Waterfall 방식 대비 Agile 방법의 장점에 대해 많이 배웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Agile의 가장 큰 장점은 유지보수 비용이 적게 든다는 점&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Waterfall 방식은 요구사항 정의  &amp;rarr; 분석 &amp;rarr; 설계 &amp;rarr; 개발 &amp;rarr; 테스트 &amp;rarr; 배포 &amp;rarr; 유지보수 순으로 진행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요구사항 정의부터 배포까지의 단계가 더 많지만 &lt;u&gt;&lt;b&gt;비용 자체는 유지보수가 압도적이다&lt;/b&gt;&lt;/u&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요건대로 개발했음에도 유지보수할 것은 끊임없이 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 Agile 방식을 선택하면 되잖아!!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 Agile을 사용하는 기업은 그리 많지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 조직인 만큼 조직 구조가 수직적이고 각 단계별 실무 담당자, 책임자가 명확히 구분되어 있기에 Waterfall 방식을 선호하는 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;i&gt;그러므로 우리는 유지보수의 늪에서 쉽게 빠져나올 수 없다!!!&lt;/i&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 게시글에서 하고 싶은 말은 유지보수할 일이 많다! 남이 짠 코드를 내가 수정해야하는 일이 많다! 그냥 일이 많다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 일을 한꺼번에 처리하다보면 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;A 개발건&lt;/span&gt;&lt;/b&gt;을 처리하기 위해 건들인 코드 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;a-1&lt;/span&gt;&lt;/b&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-2&lt;/b&gt;&lt;/span&gt;, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;a-3&lt;/span&gt;&lt;/b&gt;과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;B 개발건&lt;/span&gt;&lt;/b&gt;을 처리하기 위해 건들인 코드 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;b-1&lt;/b&gt;&lt;/span&gt;, &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;b-2&lt;/span&gt;&lt;/b&gt;, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;b-3&lt;/b&gt;&lt;/span&gt;이 헷갈리기 시작한다....&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;바로 이 것이 오늘 내가 저지른 실수의 핵심이다!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 평소에 특정 개발건을 처리하기 위해 건들인 코드들을 한번에 SVN에 Commit한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Commit message에 어떤 것들을 수정했는지 대강 작성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추후에 형상 관리 시스템을 통해 운영에 코드를 최종 배포할 때 나는 Commit 이력과 Commit message를 보고 소스 코드를 선택하여 배포한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 외에는 따로 각 개발건에 대해 어떤 코드들을 건드렸는지 기록하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘의 실수에 대해 먼저 간략히 설명하자면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;A 개발건&lt;/b&gt;&lt;/span&gt;을 처리하고 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-1&lt;/b&gt;&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-2&lt;/b&gt;&lt;/span&gt;를 우선 Commit 한 후 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;B 개발건&lt;/b&gt;&lt;/span&gt;을 처리하다가 &lt;u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;A 개발건&lt;/b&gt;&lt;/span&gt; Commit 시 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-3&lt;/b&gt;&lt;/span&gt;이 빠졌다는 것을 알게 되었다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 그때 이미 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;b-1&lt;/b&gt;&lt;/span&gt;을 개발 완료한 상태여서 &lt;u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-3&lt;/b&gt;&lt;/span&gt;과 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;b-1&lt;/b&gt;&lt;/span&gt;을 함께 Commit 해버렸다&lt;/u&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Commit message에는 장표 수정. 이 한마디를 기록했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;A 개발건&lt;/b&gt;&lt;/span&gt;에 대한 테스트가 끝나고 형상 관리 시스템에서 최종 배포를 할 때 &lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;어떤 코드를 수정했더라?&quot; &lt;/span&gt;&lt;/i&gt;라고 생각하며 Commit 이력을 봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;a-1&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; a-2&lt;/span&gt;&lt;/b&gt; | &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-3&lt;/b&gt;&lt;/span&gt;, &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;b-1&lt;/span&gt;&lt;/b&gt; 이렇게 두 개의 Commit을 보고는 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;i&gt;&quot;아! 첫번째 Commit이 A 개발건이고 두 번째 Commit이 B 개발건인가보다!&quot;&lt;/i&gt;&lt;/span&gt; 라고 생각하며 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-1&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;&lt;b&gt; a-2&lt;/b&gt;&lt;/span&gt; 만 골라 최종 배포했다....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포가 완료되고 운영에 수정 사항이 정상적으로 반영되었는지 확인하던 중 &lt;u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-3&lt;/b&gt;&lt;/span&gt;이 반영이 안 된 것을 발견했다&lt;/u&gt;!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 문제를 이 잡듯이 뒤진 결과...... 내가 배포할 소스 코드 하나(a-3)를 빼먹은 것을 알게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;b-1&lt;/b&gt;&lt;/span&gt;과 함께 Commit 하는 바람에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;B 개발건&lt;/b&gt;&lt;/span&gt;에 관련된 소스 코드라고 생각한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;a-3&lt;/b&gt;&lt;/span&gt;을 추가해서 배포하긴 했지만,,,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사건으로 &lt;u&gt;&lt;b&gt;수정한 소스 코드를 리스트로 관리하는 것이 얼마나 중요한 것인지&lt;/b&gt;&lt;/u&gt; 뼈저리게 느끼게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법은 뭐든 상관없다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수기로 종이에 작성해도 좋고, 엑셀로 정리해도 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐든 어떤 개발건에 어떤 코드를 수정했는지 기록을 해두지 않는다면 나와 같은 대참사가 발생할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 내일 출근하자마자 엑셀 파일을 하나 만들 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엑셀 외에 더 좋은 방법이 있다면 함께 공유하면 좋을 것 같다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 총 6개 정도의 개발 건을 수행했는데 그중 2개에서 지금과 같은 문제가 생겼었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정한 소스 코드 리스트 관리 이후 오류가 얼마나 줄었는지는 이후 게시글로 공유하겠다!&lt;/p&gt;</description>
      <category>개발 공부</category>
      <category>it</category>
      <category>개발</category>
      <category>소스코드</category>
      <category>코드관리</category>
      <category>형상관리</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/66</guid>
      <comments>https://vvs010.tistory.com/66#entry66comment</comments>
      <pubDate>Wed, 26 Nov 2025 23:27:20 +0900</pubDate>
    </item>
    <item>
      <title>버전 관리를 하자!</title>
      <link>https://vvs010.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;얼마 전부터 리포트 관련 개발을 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Clip Report 라는 툴을 사용해서 crf 문서를 만들고 웹 사이트에서 출력 버튼을 누르면 해당 crf 파일을 띄우게끔 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 유지보수를 하고 있기 때문에 새로운 문서를 만들기 보다 기존에 있던 문서를 수정하여 반영하는 일이 더 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 문서를 수정할 때 나는 크게 두 가지 방식을 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. 기존 문서 파일을 변형한다.&lt;br /&gt;2. 기존 문서 파일은 그대로 두고 새로운 문서를 만들어 새로운 파일로 코드를 연결한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 수정을 하는 것인지, 수정의 규모가 어떻게 되는지, 그 팀의 개발 규칙 등에 따라 선택하는 방식이 달라질 수 있겠지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 2번을 압도적으로 지지한다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 나는 금융권 종사자임을 밝힌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리나라에서 금융권은 굉장히 많은 규제를 받고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;정말이다.. 실제로 정말 많은 규제가 있기에 비금융권 회사들이 금융권에 쉽게 발 들이지 못하는 것으로 알고 있다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'규제 = 불편하고 나쁜 것' 은 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규제가 있기에 우리가 안전한 금융망 속에서 자유롭게 돈 거래를 할 수 있기 때문이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 규제를 관할하는 기관은 여러 군데가 있는데 그 중 하나를 꼽자면 금융감독원을 꼽을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금융감독원은 금융소비자의 여러 민원을 처리할 뿐만 아니라 금융 기관이 규제를 잘 지키고 있는지 감사하고 지적하고 개선하도록 관장하는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 쉽게 예를 들어보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느 날 고객 고지 의무가 한가지 추가되어 리포트를 수정하는데 이때 1번 방식을 택했다고 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 방식대로 리포트를 수정하여 운영하다가 갑자기 금융감독원에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;&quot;너네 올해 장표 수정한 것들 이력 좀 보자.&quot;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 한다면 어떻게 해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋한 내용을 &lt;u&gt;모두 Rollback&lt;/u&gt; 하거나 형상 관리 툴에서 &lt;u&gt;이전 버전을 모두 찾아 다운로드&lt;/u&gt;를 받아야할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;말도 안되는 노가다 작업에 몇날며칠을 쏟을지 상상도 안간다...&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 내가 만약 2번 방식을 채택했다면 어떻게 됐을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;VLD_EDT &amp;lt;= SYSDATE 인 데이터를 모아 파일들을 제출하면 끝!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 회사들이 그렇겠지만 금융권은 특히 내부감사, 외부감사에 항상 대비하고 있어야하기 때문에 버전 관리는 무엇보다 중요한 과제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러가지 버전 관리 방법을 사용하고 있지만 오늘은 그 중 DB에 버전 관리하는 방법을 소개할까 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB에서 &lt;b&gt;PK(Primary Key)는 기본키라는 뜻으로 테이블의 각 행을 고유하게 구분하기 위해 사용되는 하나의 컬럼&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키는 후보키 중 하나로 선정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2개 이상의 후보키 중 기본키로 선택되지 못한 나머지 키는 대체키로 남는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 &lt;u&gt;&lt;b&gt;후보키를 2개 두는 방식&lt;/b&gt;&lt;/u&gt;으로 버전을 관리했다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;문서 ID&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;순서 번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;파일 이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;사용여부&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;유효시작일&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;유효종료일&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;D0001&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;D0001.crf&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;N&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;20010201&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;20251123&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;D0001&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;D0002.crf&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;20251124&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;99991231&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 DB 테이블에서 후보키는 &lt;b&gt;문서 ID&lt;/b&gt;와 &lt;b&gt;순서 번호&lt;/b&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 문서 ID 값은 유일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 파일을 찾는 쿼리의 첫 조건절은&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;WHERE&lt;/span&gt; 문서 ID = #문서 ID#&lt;/b&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 내가 장표를 개정하여 새로운 파일을 만들고, 이제부터 새롭게 만든 파일을 호출해야한다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 위처럼 문서 ID는 이전 버전과 동일하게 두고 순서 번호를 다음 숫자로 갱신하여 등록할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 이전 버전 파일의 데이터에서는 &lt;b&gt;사용여부&lt;/b&gt;와 &lt;b&gt;유효종료일&lt;/b&gt; 값이&amp;nbsp;변경된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 파일을 찾는 쿼리의 다음 조건절은&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;AND&lt;/span&gt; 순서 번호 = MAX(순서 번호) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;AND&lt;/span&gt; 사용여부 = 'Y' &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;AND&lt;/span&gt; 유효종료일 &amp;gt;= SYSDATE&lt;/b&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 나는 D0002.crf 파일에 대한 데이터를 뽑아낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에 또 D0001 파일을 수정해야될 때가 오면 그때는 순서 번호를 3으로 하고 D0002.crf의 사용여부와 유효종료일을 업데이트하면 된다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 DB로 간단하게 버전관리하는 방법을 알아봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규제때문이 아니더라도 버전 관리는 굉장히 유용한 기술이라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IT 관련 종사자가 아닌 타 업종 종사자들에게도 유용한 정보가 되었으리라 믿는다!&lt;/p&gt;</description>
      <category>개발 공부</category>
      <category>DB</category>
      <category>SQL</category>
      <category>버전관리</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/65</guid>
      <comments>https://vvs010.tistory.com/65#entry65comment</comments>
      <pubDate>Tue, 25 Nov 2025 00:13:35 +0900</pubDate>
    </item>
    <item>
      <title>라이브러리 import의 중요성</title>
      <link>https://vvs010.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;며칠동안 골머리를 앓던 문제를 해결했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제의 원인은 &lt;b&gt;&lt;u&gt;라이브러리를 적절히 import하지 않았다는 것&lt;/u&gt;&lt;/b&gt;이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인 프로젝트나 부트 캠프 등에서는 주로 Springboot와 React를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현 회사에서는 Nexacro와 Nexcore라는 프레임워크를 쓰고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱 봐도 생소해보이지만 실제로 사용해보니 Springboot, React와 별반 다르지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 Nexacro로 프론트엔드 개발을 하면서 발생한 에러를 잡지 못해서 며칠간 고생을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 드디어 에러의 가장 큰 원인을 찾았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발을 해본 사람이라면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;'&lt;span style=&quot;color: #666666;&quot;&gt;라이브러리를 import하지 않고 해당 라이브러리의 함수를 가져다 쓰려고 하면 당연히 에러가 나지! 이걸 누가 몰라?' &lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 생각할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 기본 중의 기본이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 너무나 기본적인 개념이기 때문에 쉽게 지나칠 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기업에서 개발 실무를 보게 되면 주로 유지보수, 운영을 하게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음부터 끝까지 새롭게 코드를 짜는 일은 흔치 않은 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유지보수를 할 때 가장 어려운 점은 &lt;b&gt;&lt;u&gt;내가 아닌 남이 짠 코드를 이해하고 수정해야한다는 점&lt;/u&gt;&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 시간도 오래 걸리고 실수할 가능성도 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;이러한 실수를 한 기념으로 기본 중의 기본! 라이브러리에 대해 복습해보려고 한다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 라이브러리(library)란 뭘까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영어 단어 자체의 뜻으로 보면 도서관이라는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 도서관에서 원하는 책을 찾아 빌려볼 수 있지만,&amp;nbsp;그 책은 내 것이 아니고 도서관에 종속되어 있다는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발에서의 라이브러리도 동일한 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 라이브러리에 있는 함수, 클래스 등을 원하는 만큼 가져다 쓸 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;여기서 주의해야할 점은 2가지이다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;1. 내가 원하는 책이 있는 도서관을 찾아가야한다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;2. 도서관을 언급해주지 않으면 책을 찾을 수 없다.&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무슨 말일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 예를 들어 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 문자열의 알파벳을 모두 대문자로 바꾸는 함수가 필요하다고 가정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. String 값을 대문자로 바꿔주는 함수가 있는 라이브러리를 찾아가야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 코드에서 해당 라이브러리를 반!드!시! import해야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 2가지 주의점을 고려하여 간단히 코드를 짜면 아래와 같이 짤 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1763559705922&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.apache.commons.lang3.StringUtils;

public class Main {
    public static void main(String[] args) {
        System.out.println(StringUtils.capitalize(&quot;hello&quot;));
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 작성하면 모든 알파벳을 대문자로 바꿔주는 함수를 따로 정의하지 않더라도 쉽게 외부의 기능을 가져다 쓸 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 내가 import를 하지 않고 Main 코드를 돌리면 어떻게 될까?&lt;/p&gt;
&lt;pre id=&quot;code_1763559946290&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Error:(5, 27) java: cannot find symbol
  symbol:   variable StringUtils
  location: class Main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 에러가 발생할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 경우, 글로벌 함수로 정의된 함수를 사용하는 코드에서 위와 같은 에러가 발생하지 않고 아예 해당 코드가 실행되지 않는 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아무리 trace를 찍어봐도 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;(javascript 코드였다)&lt;/s&gt;&lt;/span&gt; console에 로그가 찍히질 않았다.....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로는 절대 이런 일로 시간을 헛되이 보내지 않도록 외부 함수 혹은 글로벌 함수를 사용할 때 적절한 라이브러리가 import 되어 있는지는 기본적으로 확인하는 습관을 들여보자!!&lt;/p&gt;</description>
      <category>백엔드</category>
      <category>import</category>
      <category>Library</category>
      <category>Trace</category>
      <category>라이브러리</category>
      <category>에러</category>
      <author>삐삐에스</author>
      <guid isPermaLink="true">https://vvs010.tistory.com/64</guid>
      <comments>https://vvs010.tistory.com/64#entry64comment</comments>
      <pubDate>Wed, 19 Nov 2025 22:51:45 +0900</pubDate>
    </item>
  </channel>
</rss>