오토파지(자가포식)란
오토파지(autophagy)는 '스스로(auto) 먹는다(phagy)'는 뜻으로, 세포가 영양 부족 등 스트레스 상황에 처했을 때 세포 내부의 불필요하거나 손상된 단백질, 미토콘드리아 등을 분해하여 새로운 에너지원이나 구성 성분으로 재활용하는 현상입니다. 이 과정은 세포를 청소하고 재정비하는 역할을 합니다. 
36시간 단식과 오토파지
  • 활성화 시점: 오토파지 작용은 보통 12~16시간의 공복 상태에서 시작됩니다.
  • 촉진 단계: 24시간 이상, 특히 36시간가량의 공복이 유지되면 오토파지가 더 활발하게 일어나는 것으로 알려져 있습니다.
  • 비정상 세포 분해: 이 과정에서 오래되거나 손상된 세포 구성 요소들이 분해되고, 세포의 노화를 늦추는 데 기여할 수 있습니다. 
36시간 단식의 건강 효과
  • 체내 청소 및 해독: 공복 상태가 길어지면 몸은 체지방을 에너지원으로 사용하고, 이 과정에서 손상된 세포 구성 물질을 분해하여 몸을 깨끗하게 청소하는 효과를 얻을 수 있습니다.
  • 체중 감량: 단식은 체지방을 에너지로 활용하기 때문에 체중 감량에 도움을 줍니다.
  • 대사 건강 개선: 인슐린 민감성을 높여 혈당 조절에 긍정적인 영향을 미칠 수 있습니다. 
주의사항 및 위험성
36시간 단식은 오토파지 활성화에 효과적일 수 있지만, 모든 사람에게 안전한 것은 아닙니다. 
  • 전문가 상담: 당뇨병, 저혈압 등 만성 질환이 있거나 노인, 임산부 등은 단식을 시도하기 전에 반드시 전문가와 상담해야 합니다.
  • 근육 손실: 장시간 단식은 근육 손실로 이어질 수 있으므로, 적절한 영양 섭취와 운동을 병행해야 합니다.
  • 면역력 문제: 일부 연구에서는 단식 후 재생 과정에서 암 위험이 증가할 수 있다는 결과도 있으므로, 특정 질환을 치료할 목적으로 단식에 의존해서는 안 됩니다. 
중요: 36시간 단식은 오토파지 활성화를 돕지만, 질병 치료의 직접적인 수단이 될 수는 없습니다. 건강 증진을 위해 단식을 시도하고자 한다면, 본인의 건강 상태를 정확하게 파악하고 신중하게 접근해야 합니다. 

 

36시간 단식 리얼 후기 : 배고픔, 두통 그리고 무의식과의 사투

최근 '자가포식(오토파지)'라는 개념을 알게 되었습니다. 36시간 공복을 유지하면 이 오토파지가 활성화되어 고장난 세포를 분해하고 새로운 세포로 재생하는 데 도움이 된다고 하더군요.

 

마침 나이가 들면서 혈액 내 염증 수치가 높다는 이야기도 들었고, 이유 없이 몸 이곳저곳이 가려운 느낌도 있었습니다. '혹시 이게 내 몸을 리셋하는 데 도움이 되지 않을까?' 하는 생각에 36시간 단식을 시도해보기로 마음먹었습니다.

 

개인적인 일로 오전 반차를 사용한 어느 날, 마지막 식사로 알리오 올리오 파스타를 가볍게 먹고 오전 10시, 드디어 36시간을 목표로 한 단식을 시작했습니다.

 

1일 차 : 배고픔보다 무서운 '습관'

단식 2시간 만에 출근길에 올랐습니다. 그리고 고작 4시간째, 오후 2시가 되자 어김없이 배가 고파오기 시작했습니다. 항상 커피를 입에 달고 살았는데, 물만 마시려니 입이 텁텁하고 물 마시는 횟수만 늘어났습니다.

 

하지만 신기하게도 오후 5시가 되자 배고픔은 사라졌습니다. 진짜 싸움은 그때 부터였습니다.

 

저녁 7시, 퇴근길에 늘 지나치던 식당가를 지날 때 였습니다. 만두 가게 앞을 지나며 '오늘 저녁은 만두다' 라고 생각한 순간, "아, 나 단식 중이지"라는 사실을 깨달았습니다. 배가 고프지 않은데도, 습관이 저를 식당으로 이끌고 있었습니다.

 

집에 와서도 '무의식'과 사투는 계속되었습니다. 밤 8시, 다용도실 청소를 하다가 발견한 프링글스에 저도 모르게 손이 뻗어 나갔습니다. 과자통에 손이 닿기 직전에야 정신을 차릴 수 있었죠.

 

밤 10시, 단식을 시작하고 12시간이 지나자 다시 배가 고파오고 머리가 살짝 아파왔습니다. 주말에 커피를 마시지 않을 때 생기는, 익숙한 두통이었습니다. '배고파서 잠 못 들면 어떡하지'라는 걱정과 함께 잠자리에 들었습니다.

 

2일 차 : 맑은 정신? 아니, 흐릿한 초점

오전 6시, 단식 20시간째 아침. 특별히 몸이 개운하거나 가벼운 느낌은 없었습니다. 배고픔은 사라졌지만 두통은 여전했습니다.

 

오전 8시, 출근길. 지하철역까지 1km 정도를 뛰어야 했습니다. '에너지가 부족해서 힘들지 않을까?' 걱정했지만, 웬걸, 평소와 비슷했고 오히려 조금 가벼운 느낌마저 들었습니다. 문득 '그동안 내가 너무 많이 먹고 살았나?' 하는 생각이 스쳤습니다.

하지만 평화는 오래가지 않았습니다.

 

오전 9시, 평소 아침(김밥이나 샌드위치)를 먹던 시간이 되자 귀신같이 배가 고파오기 시작했습니다. 역시 습관적인 배고픔이었습니다.

 

단식 24시간을 넘긴 오전 11시, 가장 힘든 순간이 찾아왔습니다. 배는 고프지 않은데, 업무를 위해 글씨를 보려니 눈의 초점이 자꾸 풀렸습니다. 집중력은 바닥을 쳤고, 판단력도 평소보다 현저히 느려진 느낌이었습니다. 점심시간에는 배고픔보다 졸음이 몰려와 잠깐 눈을 붙여야 했습니다.

 

단식 종료 : 그리고 마지막 깨달음

오후 9시, 35시간째. 고비는 넘긴 듯했습니다. 배는 고프지 않았고, 빨래를 개는 등 일상생활도 문제없었습니다. 이제 머릿속은 '단식이 끝나면 뭘 먹을까'하는 행복한 고민으로 가득 찼습니다.

 

그리고 마침내 오후 10시, 36시간의 단식이 끝났습니다.

 

저는 기쁜 마음으로 초밥을 주문했습니다. 하지만 배달은 도착가지 40분이나 걸린다고 했습니다. 그 화면을 보는 순간 36시간 동안 잠잠했던 배고픔이 미친 듯이 몰아쳤습니다.

 

그리고 드디어 만난 초밥.

 

한 입 먹는 순간, 이런 생각이 들었습니다. "초밥이... 이렇게 맛있는 음식이었나?"

 

그리고 결심했습니다. "단식은 무슨 개나 줘 버려."

 

제 생애 첫 36시간 단식 도전은 이렇게 끝이 났습니다. 몸속의 에너지를 쓰는 느낌, 그리고 습관이 얼마나 무서운지 깨닫게 된 소중한 경험 이었습니다.

 

[에필로그] 그로부터 일주일 후

단식이 끝나고 일주일이 지났습니다. 그래서 몸이 좀 달라졌냐고요? 솔직히 말하면... 잘 모르겠습니다. 오토파지의 기적은 일어났을까요? 적어도 제가 느끼기엔, 단식 시작 전과 거의 비슷합니다.

 

염증 수치나 가려움증이 극적으로 나아진 것은 체감하기 어려웠지만, 36시간을 버텨냈다는 뿌듯함은 남았네요.

 

하지만 역시 두 번 다시 하고 싶지는 않습니다. 사람은 맛있는 것을 먹어야 합니다!

 

MSSQL 사용자의 기본 데이터베이스(Default DB)는 SSMS (GUI) 또는 T-SQL (쿼리) 두 가지 방법으로 간단히 설정할 수 있습니다.


1. SSMS (SQL Server Management Studio) 이용 (GUI)

가장 직관적인 방법입니다.

  1. SSMS에 접속한 후, **개체 탐색기(Object Explorer)**를 엽니다.
  2. 보안(Security) 폴더를 확장하고 로그인(Logins) 폴더를 선택합니다.
  3. 설정을 변경할 사용자 로그인을 찾아 마우스 오른쪽 버튼으로 클릭한 뒤 속성(Properties)을 선택합니다.
  4. 로그인 속성 창의 일반(General) 페이지 하단에 있는 기본 데이터베이스(Default database) 드롭다운 메뉴를 찾습니다.
  5. 원하는 데이터베이스를 선택하고 확인 버튼을 클릭합니다.
사용자 로그인 - 속성(Properties)
속성 창의 일반(General) 페이지 하단에 있는  기본 데이터베이스(Default database)  드롭다운 메뉴

2. T-SQL (쿼리) 이용

ALTER LOGIN 명령어를 사용하여 설정할 수 있습니다.

-- 'master' 데이터베이스 컨텍스트에서 실행하는 것이 좋습니다.
USE master;
GO

ALTER LOGIN [변경할_로그인_이름]
WITH DEFAULT_DATABASE = [기본으로_설정할_DB이름];
GO

예시:

MyUser라는 로그인 계정의 기본 DB를 MyDatabase로 설정하는 경우:

ALTER LOGIN [MyUser]
WITH DEFAULT_DATABASE = [MyDatabase];

💡 참고: 기본 DB란?

  • 해당 사용자가 SQL Server에 로그인할 때 가장 먼저 연결되는 데이터베이스입니다.
  • 만약 USE [DB_Name] 구문 없이 쿼리를 실행할 때, 이 기본 DB를 기준으로 쿼리가 실행됩니다.
  • 설정된 기본 DB가 삭제되거나 오프라인 상태이면, 사용자는 master 데이터베이스로 연결됩니다.

 

UTC Time 값을 조회하는 쿼리

SELECT GETUTCDATE() AS UTC_TIME

 

UTC Time값을 저장한 Datatime 변수를 Local Time으로 조회하는 함수

 

DECLARE @DT1 DATETIME
      , @DT2 DATETIME

    SELECT @DT1 = GETUTCDATE()    
	
    SELECT @DT1    // 출력값 : 2025-02-26 08:24:22.130

    SELECT @DT2 = SWITCHOFFSET(CONVERT(DATETIMEOFFSET, @DT1),DATENAME(TZOFFSET, SYSDATETIMEOFFSET()))
	
    SELECT @DT2    // 출력값 : 2025-02-26 17:24:22.130

 

 

아래 스택 오버플로우 글을 참고함.

https://stackoverflow.com/questions/8038744/convert-datetime-column-from-utc-to-local-time-in-select-statement

문제 : NodeJS로 구성된 API서버에서 입력한 시간을 MSSQL 서버에 입력 시 간혹 1 밀리세컨드 차이가 발생함.

원인 : NodeJS에서 MSSQL로 쿼리 생성 후 전달 시 매개변수 타입을 의도와 다르게 DateTime 으로 설정함.

해결 : MSSQL 컬럼 타입과 매개변수 타입을 DateTime2로 변경.

 

상세 내용:

의도

데이터 입력 시간을 밀리세컨드 까지 기록하려 함. [예시) 2025-01-01 13:01:00.001]

API서버는 NodeJs로 구성되어 있고, mssql 라이브러리를 require 로 가져와서 사용함.

const msdb = require('mssql');

async dbtest() {
        let now = new Date();
        console.log(now); //2025-01-01 13:01:00.001
        return (await msdb.connect(conf.db)).request()
            .input('RMK', msdb.NVarChar, 'Test Remark')
            .input('REG_DT', msdb.DateTime, now)
            .query(`insert into tb_logs (RMK, REG_DT) values (@RMK, @REG_DT)`);
    }

 

문제 확인

MSSQL DB에서 Select 쿼리로 조회해보면, 간혹 한번씩 1밀리세컨드가 더 크게 들어가 있는 것을 확인함.

console.log로 찍은건 밀리세컨드가 001 인데 MSSQL 서버에서 002로 조회됨.

MSSQL 컬럼 타입을 DateTime2로 변경해서 테스트한 후 문제 원인 추측할 수 있었음.

console.log에서 [2025-01-01 13:01:00.001] 이렇게 보이던 값이

DB에 [2025-01-01 13:01:00.0016667] 과 같이 들어가 있었고, 조회될 때 4번째에서 반올림되어 002로 조회되었음.

 

문제 해결
MSSQL 컬럼 타입과 Node.js API서버의 매개변수 타입을 msdb.DateTime2로 변경해준 뒤 

DB에 [2025-01-01 13:01:00.0010000] 으로 저장됨 확인.

const msdb = require('mssql');

async dbtest() {
        let now = new Date();
        console.log(now); //2025-01-01 13:01:00.001
        return (await msdb.connect(conf.db)).request()
            .input('RMK', msdb.NVarChar, 'Test Remark')
            .input('REG_DT', msdb.DateTime2, now) //msdb.DateTime -> msdb.DateTime2
            .query(`insert into tb_logs (RMK, REG_DT) values (@RMK, @REG_DT)`);
    }

 

-- 위 코드는 상황을 설명하기 위해 재구성하여 작성하였기에 정상적으로 동작하지 않을 수 있습니다.

 

-- 개인적인 생각. 

공식 문서에는 DateTime2가 0.0000001 초까지 기록된다고 되어있는데, node의 mssql 라이브러리 버그인걸까?

mssql은 7.3.5 버전을 사용중...

Nodejs로 API 서버 구현 중 MSSQL을 사용한다.

2개의 다른 MSSQL 서버와 연결하여 데이터를 활용하려 한다.

* 아래 코드는 테스트를 위해 임시로 만든 코드이다.

 

문제 : 아래와 같이 2개 MSSQL 서버 속성을 다르게 설정하고, mssql 모듈을 2번 불러와 사용하려 했는데,

          최초 연결한 DB 서버가 pool에 들어가 있어서 인지, 다른 속성으로 Connect를 시도하여도

          이미 pool이 생성되어있던 DB서버에 쿼리를 날려버린다.

// db.js
let conf = require(./conf);

const msdb1 = require('mssql');
const msdb2 = require('mssql');

module.exports = {

    async dbtest1() {
        return (await msdb1.connect(conf.db1)).request()
            .input('NM_ID', msdb1.NVarChar, 'test_id1')
            .input('RMK', msdb1.NVarChar, 'TEST Remark1')
            .query(`insert into tb_logs (NM_ID, RMK) values (@NM_ID, @RMK)`);
    }
    
    
    async dbtest2() {
        return (await msdb2.connect(conf.db2)).request()
            .input('NM_ID', msdb2.NVarChar, 'test_id2')
            .input('RMK', msdb2.NVarChar, 'TEST Remark2')
            .query(`insert into tb_logs (NM_ID, RMK) values (@NM_ID, @RMK)`);
    }
}

 

 

해결 방안 : 스택 오버플로우에 답변을 올려주신 분이 있어서, 해당 코드를 참고하였다. (매우 감사한 분이다.)

                  GetCreateIfNotExistPool 함수명이 싫어서 기존과 동일한 connect 로 함수를 변경하여 사용했다.

                  1. 여러 MSSQL DB의 커넥션 풀을 관리하는 mssql-connection-pooling.js 파일을 하나 만든다.

                      - 이 파일에서는 여러 MSSQL DB의 커넥션 풀을 pools 객체에 넣어관리한다.
                      config 객체를 문자열로 만든 뒤 key로 사용한다.

                      connection을 요청할 때 동일한 key가 있다면 pools에서 해당 pool을 제공한다.

                      동일한 key가 없으면 새로운 pool을 연결하여 pools 에 새로 넣어놓고 pool을 제공한다.

                  2. mssql-connection-pooling.js 파일을 기존 코드에 불러와 사용한다.

 

// mssql-connection-pooling.js 파일 코드
const { ConnectionPool } = require('mssql');
const pools = {};

// 새로운 커넥션 풀 생성
function CreatePool(config) {
    let key = JSON.stringify(config);

    if (GetPool(key)) {
        throw new Error('Pool already exists');
    }

    pools[key] = (new ConnectionPool(config)).connect();
    return pools[key];
}

// pools 안에 생성된 connection pool 받기
function GetPool(name) {
    if (pools[name]) {
        return pools[name];
    } else {
        return null;
    }
}

// pool이 생서되어 있으면 return pool, 없으면 새로 생성
function connect(config) {
    let key = JSON.stringify(config);

    let pool = GetPool(key);
    if (pool) {
        return pool;
    } else {
        return CreatePool(config);
    }
}

function ClosePool(config) {
    let key = JSON.stringify(config);

    if (pools[key]) {
        const pool = pools[key];
        delete pools[key];
        pool.close();
        return true;
    }
    return false;
}

// 모든 pool 종료
function CloseAllPools() {
    pools.forEach((pool) => {
        pool.close();
    });
    pools = {};
    return true;
}

module.exports = {
    ClosePool,
    CloseAllPools,
    CreatePool,
    GetPool,
    connect,
}

 

// db.js //수정본
let conf = require(./conf);

const msdb = require('mssql');
const mssql = require('./mssql-connection-pooling.js')
//const msdb1 = require('mssql');
//const msdb2 = require('mssql');


module.exports = {
    async dbtest1() {
        return (await mssql.connect(conf.db1)).request()
            .input('NM_ID', mssql.NVarChar, 'test_id1')
            .input('RMK', mssql.NVarChar, 'TEST Remark1')
            .query(`insert into tb_logs (NM_ID, RMK) values (@NM_ID, @RMK)`);
    }
    
    
    async dbtest2() {
        return (await mssql.connect(conf.db2)).request()
            .input('NM_ID', mssql.NVarChar, 'test_id2')
            .input('RMK', mssql.NVarChar, 'TEST Remark2')
            .query(`insert into tb_logs (NM_ID, RMK) values (@NM_ID, @RMK)`);
    }   
}

 

참조 : https://stackoverflow.com/questions/64254145/node-js-mssql-multiple-concurrent-connections-to-sql-servers-interfering-with-ea

 

Node.js mssql multiple concurrent connections to SQL servers interfering with each other

I am using mssql in my Node.js express application to make connections to many different databases across many different SQL servers. I have constructed the following example to demonstrate the gen...

stackoverflow.com

 

 

Vue2에서 eslint-plugin-vue를 사용한다면, 하위 컴포넌트의 slot에 v-text 또는 v-html을 전달하여 사용할 때 간혹 아래와 같은 오류가 발생한다.

 

vue/no-v-text-v-html-on-component error

 

원인은 아래 코드와 같이 하위 컴포넌트를 사용하며 v-text를 속성으로 전달하여 사용하도록 작성된 것이다.

<child-component v-text="ABC" />

 

v-text를 속성으로 전달할 경우, 하위 컴포넌트의 콘텐츠를 덮어쓰기 하며 컴포넌트가 정상적으로 동작하지 않을 수 있기 때문에 eslint-plugin-vue에서 error 로 표시한다.

 

해결 방법은 v-text를 하위 컴포넌트 내부에 div 태그나 p 태그로 전달하면 된다.

<child-component>
	<div v-text="ABC"/>
</child-component>

 

 

다른 방법으로는 eslint에서 특정 라인을 검사하지 않도록 처리하는 방법이 있으나, 추천하진 않는다.

<!-- eslint-disable-next-line vue/no-v-text-v-html-on-component -->
<child-component v-text="ABC" />

 

해당 오류를 수정하기 위해서 아래 사이트를 참고하였다.

https://eslint.vuejs.org/rules/no-v-text-v-html-on-component.html

 

vue/no-v-text-v-html-on-component | eslint-plugin-vue

 

eslint.vuejs.org

https://stackoverflow.com/questions/75698069/disable-eslint-error-with-vuejs-and-v-html

 

Disable eslint error with Vuejs and v-html

I use Nuxt 2 with Vue 2 and vuetify. My vscode was updated and I am getting an eslint error with v-html. The code is: <v-list-item-title v-html="`${parent.genFilteredText(item.nome)}`&q...

stackoverflow.com

 

SSMS에서 임시테이블을 사용하여 데이터를 확인하는 쿼리를 사용하다보면,

임시테이블을 제거(DROP)하고 다시 생성해서 사용해야하는 경우가 있다.

 

쿼리의 마지막 라인에 사용한 임시테이블을 제거(DROP)하는 방법으로 쿼리 작성도 가능하지만

실행 시 임시테이블이 있는지 확인하고 있다면 지우고 다시 생성하도록 하는 방법도 있다.

 

    SELECT *
      INTO #TEMP_TT
      FROM (
            SELECT 'A' AS T UNION ALL
            SELECT 'B' AS T UNION ALL
            SELECT 'C' AS T
           ) A

    SELECT *
      FROM #TEMP_TT

<임시테이블에 데이터를 입력하고 입력된 데이터를 확인하는 쿼리>

위 쿼리를 처음 실행하면 아래와 같이 정상적으로 실행된다.

정상실행 화면

 

위 쿼리를 다시한번 실행하면 아래와 같은 오류가 발생한다.

MSSQL ERROR MESSAGE - 메시지 2714, 수준 16, 상태 6, 줄 2 데이터베이스에 '#TEMP_TT'(이)라는 개체가 이미 있습니다.

 

쿼리 상단에 아래와 같은 코드를 넣어주면, 쿼리 실행 시 임시테이블의 존재 여부를 확인하고 

임시테이블이 있다면 제거 후 쿼리를 실행하게 된다.

* #이 2개 붙어있는 전역 임시테이블에 사용할 때는 다른 SESSION에서 사용되고 있을 수 있으니 주의해야한다.

    IF OBJECT_ID('TEMPDB..#TEMP_TT') IS NOT NULL
    BEGIN
        DROP TABLE #TEMP_TT
        PRINT 'DROP TABLE #TEMP_TT.'
    END
    ELSE
    BEGIN
        PRINT '#TEMP_TT IS NOT EXISTS.'
    END

    SELECT *
      INTO #TEMP_TT
      FROM (
            SELECT 'A' AS T UNION ALL
            SELECT 'B' AS T UNION ALL
            SELECT 'C' AS T
           ) A

    SELECT *
      FROM #TEMP_TT

임시테이블이 있다면 제거 후 쿼리를 실행할 수 있도록 조건문 추가.

 

위 쿼리를 실행하면 아래와 같이 임시테이블 존재 여부에 따라 메시지가 표시되며, 정상 실행된다.

임시테이블 확인 후 제거
정상실행

 

취미용으로 장난감을 만들며 놀기 위해 1.29 inch OLED LCD 화면을 구입했습니다.

 

제품 설명에 CH1115 호환 SSD1306 이라고 적혀있기에 SSD1306을 검색하여

 

가장 많이 나오는 Adafruit_SSD1306 라이브러리를 사용하여 테스트 용 코드를 작성하였습니다.

 

결과는 아래 사진과 같이 나와서 깜짝 놀랐습니다.

 

Adafruit_SSD1306.h 사용

 

어디가 잘못된건지 감도 못잡겠고, SSD1306, CH1115 로 검색해봐도 Adafruit 라이브러리만 보여서 답답했습니다.

 

결과적으로 유튜브 영상에서 U8glib 라이브러리를 알게 되었습니다.

 

아래는 U8glib 라이브러리를 사용하여 테스트용 코드를 작성했을 때 모습입니다.

 

U8glib.h 사용

 

테스트에 사용한 코드를 같이 남겨놓습니다.

#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI

int progress = 0;

void setup() {
  // put your setup code here, to run once:
  u8g.setFont(u8g_font_tpssb);
  u8g.setColorIndex(1);
}

void loop() {
  // put your main code here, to run repeatedly:
  u8g.firstPage();
  do{
    u8g.drawStr(25,50,"Progress Bar");
    u8g.drawFrame(0, 10, 128, 20);
    u8g.drawBox(10,15,progress, 10);
  } while (u8g.nextPage());

  if (progress < 108)
  {
    progress++;
  } 
  else 
  {
    progress = 0;
  }
}

 

아래에 구매한 제품과 참고한 유튜브 영상의 링크를 같이 남겨놓습니다.

 

 

 

숫자형 데이터를 문자형 데이터로 변경할 때 앞에 0을 채워서 지정된 길이로 만들어 사용하고 싶을 때가 있습니다.

단순히 CONVERT를 사용하면 앞에 0이 채워지지 않은 상태로 숫자만 문자형으로 변경되기 때문에

다른 방법을 사용해야 합니다.

 

FORMAT 함수를 사용하면 앞에 0을 채워 지정한 길이의 문자열로 만들어 사용할 수 있습니다.

 

    -- FORMAT 함수를 사용하여 숫자를 10자리 문자열로 변경
    SELECT FORMAT(1230,'0000000000') AS FORMATTED_TEXT

    -- CONVERT 함수를 사용하여 숫자를 문자로 변경
    SELECT CONVERT(NVARCHAR(10),1230) AS CONVERTED_TEXT

 

위 코드를 실행하면 아래와 같은 결과가 나옵니다.

코드 실행 결과

 

기타 다른 상황에 대한 실행 결과

    -- 숫자 길이가 서식보다 길 때
    SELECT FORMAT(12345678901234567890,'0000000000') AS FORMATTED_OVER_TEXT
    
    -- 숫자를 3자리 마다 쉼표로 구분하고 싶을 때
    SELECT FORMAT(12345678901234567890,'0,000,000,000') AS FORMATTED_COMMAS_TEXT

    -- 숫자 앞에 문자를 고정으로 넣어주고 싶을 때
    SELECT FORMAT(12345678901234567890,'FORMATTED_0000000000') AS FORMATTED_COMMAS_TEXT

코드 실행 결과

LAG 함수를 통해 이전 데이터의 값을 가져와 계산에 사용할 수 있다.

SQL Server2012버전 이후 부터 사용 가능하다.

 

사용방법

 

SELECT 문에 함수 작성.

LAG(컬럼명, 이전 행 수, 이전 행이 없을 때 기본값) OVER ( PARTITION BY 그룹으로 묶을 컬럼 리스트

                                                                                               ORDER BY 이전행을 찾을 때 사용할 정렬 기준)

파란색 으로 표시한 글자 생략 가능

/*********************************
* 이전 행 데이터 가져와 계산 TEST 쿼리
**********************************/

-- 1. TEST에 필요한 BASE DATA 만들기

    SELECT A.ITEM
         , A.VALUE
      INTO #TEMP1
      FROM (
            SELECT 'A' ITEM, 1 VALUE UNION ALL
            SELECT 'A' ITEM, 2 VALUE UNION ALL
            SELECT 'A' ITEM, 3 VALUE UNION ALL
            SELECT 'A' ITEM, 4 VALUE UNION ALL
            SELECT 'A' ITEM, 5 VALUE UNION ALL
            SELECT 'B' ITEM, 6 VALUE UNION ALL
            SELECT 'B' ITEM, 7 VALUE UNION ALL
            SELECT 'B' ITEM, 8 VALUE UNION ALL
            SELECT 'B' ITEM, 9 VALUE UNION ALL
            SELECT 'B' ITEM, 10 VALUE
           ) A

-- 2. BASE DATA 확인

    SELECT *
      FROM #TEMP1

-- 3. LAG 윈도우 함수 사용

    SELECT ITEM
         , VALUE
         , LAG(VALUE,1,0) OVER( PARTITION BY ITEM ORDER BY VALUE ) STACKED_SUM
      FROM #TEMP1

 

MSDN 참고

https://learn.microsoft.com/ko-kr/sql/t-sql/functions/lag-transact-sql?view=sql-server-ver16 

 

LAG(Transact-SQL) - SQL Server

LAG(Transact-SQL)

learn.microsoft.com

 

+ Recent posts