본문 바로가기

웹/Nodejs

[node.js]프로시져 사용해서 Api 만들어보기(mssql)

1. 프로시져 만들기.

CREATE  PROCEDURE dbo.test
    @CO varchar(50),
    @TOTAL int=NULL output
AS
begin
    SELECT @TOTAL = COUNT(*) from cal_meters cm2 ;
    SELECT * FROM cal_meters cm WHERE code = @CO;
end

exec dbo.test'10002-03-01';

create procedure 문으로 프로시저를 만들 수 있습니다.

함수의 매개변수 처럼 @변수명 + 타입을 써서 프로시저 안에 변수를 받을 수 있습니다.

image

calmeter의 code칼럼입니다. where문에 code를 넣어서 calmeter 전체를 가져와보겠습니다.

 

2. node.js와 mssql 연결하기

const config: config = {
  user: 이름,
  password: 패스워드,
  server: db주소,
  port: db포트,
  database: db데이터베이스이름,
  pool: { //커넥션 풀 설정
    max: 30,
    min: 1,
    idleTimeoutMillis: 30000,
  },
};

export const poolPromise = new sql.ConnectionPool(configHtms)
  .connect()
  .then((pool) => {
    console.log('Connected to MSSQL');
    return pool;
  })
  .catch((err) => console.log('Database Connection Failed! Bad Config: ', err));

module.exports = {
  sql,
  poolPromise,
};

npm -i sql을 받아서 커넥션 풀을 쓸 수 있어야 합니다. 커넥션 풀을 쓰면 한 번 db에 연결해 놓으면 커넥션 풀로 계속해서 연결 할 수 있습니다.

 

3. 컨트롤러 만들기(router의 역할)

const router = express.Router();

// Procedure로 데이터 가져오기
router.post(
  '/procedure-test',
  async (req: Request<unknown, unknown, PROCEDURE_TESTSelectListParams, unknown>, res: Response) => {
    const logFormat = makeLogFormat(req);
    const tokenUser = (req as { decoded?: Payload }).decoded;

    try {
      logging.REQUEST_PARAM(logFormat);

      // 비즈니스 로직 호출
      const result = await PROCEDURE_TESTService.listAll(req.body, logFormat);
      console.log(result);
      // 최종 응답 값 세팅
      const resJson = resSuccess(result, resType.LIST);

      return res.status(resJson.status).json(resJson);
    } catch (err) {
      // 에러 응답 값 세팅
      const resJson = resError(err);

      return res.status(resJson.status).json(resJson);
    }
  }
);

컨트롤러에서 사용자의 요청을 받고 service 로직에 넘겨서 비지니스 로직을 실행시킵니다.

POST요청으로 /procedure-test가 들어오면 service단의 listAll()이 동작할 것 입니다.

여기서에 제가 사용한 interface는 PROCEDURE_TESTSelectListParams입니다.

// selectList
export interface PROCEDURE_TESTSelectListParams {
  CO: number;
  limit?: number;
  offset?: number;
  order?: string;
}

인터페이스 형태로 변수를 받아올 수 있습니다. CO객체를 body에서 받아와야 하니 interface로 객체타입을 지정해줍니다.

 

4. 서비스 로직 만들기

const service = {
  // selectList
  async listAll(params: PROCEDURE_TESTSelectListParams): Promise<Array<any>> {
    let result: PROCEDURE_TESTSelectListResult | void;

    try {
      result = await PROCEDURETESTDao.selectList(params);
    } catch (err) {
      return new Promise((resolve, reject) => {
        reject(err);
      });
    }

    return new Promise((resolve) => {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      resolve(result);
    });
  },
};

컨트롤러에서 받은 req.body들을 Dao(db와 접촉하는 layer)에 넘겨주는 역할을 합니다.

 

5. Dao에서 db에서 값 가지고 오기

//select All
async selectList(params: PROCEDURE_TESTSelectListParams): Promise<PROCEDURE_TESTSelectListResult | void> {
    let result: PROCEDURE_TESTSelectListResult | void;
    const pool = await poolPromise;

    if (pool) {
      result = await pool
        .request()
        .input('CO', sql.VarChar(50), params.CO)
        .output('TOTAL', sql.Int, 0)
        .execute('dbo.test')
        .then((result) => {
          const result_data: PROCEDURE_TESTSelectListResult = {
            total: result.output.TOTAL as number,
            result: result.recordset,
          };
          return result_data;
        })
        .catch((err) => {
          console.log('err', err);
        });
    }

    return result;
  }

여기서 커넥션 풀을 가져와서 db의 프로시져를 실행합니다. 물론 node.js에서 sql라이브러리의 도움이 필요합니다.

  • 먼저 위에서 만든 pool객체를 가져옵니다.
  • input(변수명,타입,입력 값)을 이용해 DB프로시져 안에 CO라는 변수에 값을 넣습니다.
  • output(변수명,타입,입력 값)을 이용해 DB프로시져 에서 TOTAL라는 변수를 가져옵니다.

이제 then() 구문으로 결과(result)가 온다면 총 개수(total), 실제 결과값(result)을 반환하면 됩니다.

image

성공적으로 total값과 cal_meter의 값을 얻을 수 있게됐습니다.

 

🚩주의!

CREATE  PROCEDURE dbo.test
    @CO varchar(50),
    @TOTAL int=NULL output
AS

프로시저를 만들 때 변수 타입,크기 를 지정하게 됩니다.

.input('CO', sql.VarChar(50), params.CO)

실제 값을 넣을 때도 같은 변수 타입, 크기를 지정해줘야 합니다.

실제 db안의 칼럼 크기도 주의해서 프로시저를 만들어야 합니다. 칼럼 보다 더 작은 값으로 프로시저를 만들면 값이 안들어 갑니다.

참고

https://gameserverengineer-k.tistory.com/7

https://ahnsisters.tistory.com/7

728x90