SQL Server 임시 테이블을 Node.js에서 사용할 때의주의 사항

SQL Server에 있는 임시 테이블은 CSV 파일 등 외부에 있는 정보를 일시적으로 캡처하여 SQL로 DB에 있는 데이터와 함께 처리하고 싶을 때 유용합니다.
Azure SQL Database에서도 사용할 수 있으며 Blob 스토리지에 있는 파일을 가져오는 대상으로도 사용할 수 있습니다.

Node.js에서 Azure Functions 함수를 구현할 때 SQL Server 클라이언트mssql에서 빠진 내용을 씁니다.

TLTR



임시 테이블을 만들 때는 CREATE문을 query가 아니고, batch 를 사용한다.
이상.

샘플 코드



솔직하게 쓰면 움직이지 않는다.



SQL문의 실행은 query 메소드를 사용한다.
그래서, 임시 테이블의 작성도 query 메소드로 실행한다.

sample.js
const sql = require('mssql');

(async () => {
    try {
        var connection = await sql.connect({
            user: '**',
            password: '**',
            server: '**',
            database: '**'
        })
        var request = connection.request();
        // Create a temporary table #tmp_users
        await request.query('CREATE TABLE #tmp_users (name NVARCHAR(100) NOT NULL)')

        const names = ['Su', 'Yui', 'Moa']
        names.forEach(async (name) => {
            await request.query(`INSERT INTO #tmp_users VALUES ('${name}')`)
        })

        const result = await request.query('SELECT * FROM #tmp_users')
        console.log(result)
    } catch(err) {
        console.error(err)
    }
})();

그러나 솔직하게 query로 SQL 문을 보내 보더라도 예상대로 움직이지 않습니다. 어리석은 에러가 나오는데, 중요한 곳만 보면, 아무래도 만들었을 임시 테이블#tmp_users이 없는 것 같다.
$ node sample.js
...
RequestError: Invalid object name '#tmp_users'.
...

움직이는



sample.js
const sql = require('mssql');

(async () => {
    try {
        var connection = await sql.connect({
            user: '**',
            password: '**',
            server: '**',
            database: '**'
        })
        var request = connection.request();
        // Create a temporary table #tmp_users
        await request.batch('CREATE TABLE #tmp_users (name NVARCHAR(100) NOT NULL)')

        const names = ['Su', 'Yui', 'Moa']
        names.forEach(async (name) => {
            await request.query(`INSERT INTO #tmp_users VALUES ('${name}')`)
        })

        const result = await request.query('SELECT * FROM #tmp_users')
        console.log(result)
    } catch(err) {
        console.error(err)
    }
})();
query 대신, batch 라는 다른 메소드를 사용할 것으로 예상했던 대로 움직인다.

무슨 일이 일어나고 있는지



여러가지 조사해 보았으므로, 정리해 본다.

원래 임시 테이블이란


  • Temporary Table - CREATE TABLE (Transact-SQL) | Microsoft Docs

  • 일시적인 용도로 사용하기 위한 테이블로, 작성시의 세션안에서만 존재할 수 있다.
    세션을 끊었을 때, SQL Server에 의해 자동적으로 DROP TABLE가 실행된다.
    로컬 임시 테이블은, 접속하고 있는 세션중에서만 참조할 수 있다. 한편, 글로벌은 다른 세션으로부터도 참조가 가능하지만, 로컬과 마찬가지로, 그 임시 테이블을 작성한 세션을 끊었을 때에 삭제된다.

    그래서 Node.js 클라이언트 mssql의 query와 batch는 무엇입니까?


    mssqlREADME에 batch 설명이 있기 때문에, 거기를 보면.

    Execute the SQL command. Unlike query, it doesn't use sp_executesql, so is not likely that SQL Server will reuse the execution plan it generates for the SQL.

    그리고 있다. query 는 내부에서 sp_executesql 라고 하는 동적으로 SQL 를 실행하기 위한, 시스템이 미리 가지고 있는 스토어드 프로시저를 사용하고 있는 것 같다.

    sp_executesql에 전달되는 SQL은 다른 세션에서 실행됩니다.


  • A bit about sql server's local temp tables
  • sp_executesql 및 임시 테이블에 대한이 기사에 따르면,

    Any dynamic SQL execution with either exec() or sp_executeSQL is ran in
    a child session/scope of the current one.

    그래서 다른 세션에서 실행된다고 한다.

    요약


  • 로컬 임시 테이블은 세션 내에서만 존재할 수 있으며 해당 세션 내에서만 참조 할 수 있습니다
  • query에서 실행되는 SQL은 거기까지의 세션과는 다른 세션에서 실행된다.
  • 즉, query로 로컬 임시 테이블을 작성해도 즉시 사라집니다.

  • 라는 것을 알았습니다. 즉, 로컬 임시 테이블을 만들 때는 batch에서 실행합시다는 것입니다 .

    참고


  • 테이블 | Microsoft Docs | Microsoft Docs
  • mssql - npm
  • A bit about sql server's local temp tables
  • Scope of temporary tables in SQL Server - Stack Overflow
  • Temporary Table - CREATE TABLE (Transact-SQL) | Microsoft Docs
  • 좋은 웹페이지 즐겨찾기