SQL Server 乏味的连接从不触发任何回调

问题描述

我正在尝试连接到 Azure 中托管的 sql Server 实例。我已经验证我可以使用 DBeaver 连接到服务器,并且可以在那里浏览所有数据。

我已经安装了繁琐的使用:

npm install tedious
npm install @types/tedious

这是我正在运行的确切代码

import { Connection,ConnectionConfig,InfoObject,Request } from "tedious"

export class sqlConnection {

    private static readonly CONfig: ConnectionConfig = {
        authentication: {
            options: {
                userName: "xxx",password: "xxx"
            },type: "default"
        },server: "xxx",options: {
            database: "xxx",encrypt: true
        }
    }

    private _connection: Connection

    /**
     * Creates a new sql connection using environment variables.
     */
    public static create() {
        return new sqlConnection()
    }

    private constructor() {
        console.log("Creating connection using config")
        this._connection = new Connection(sqlConnection.CONfig)
        console.log("Connection created,creating listeners")
        this._connection.on("connect",(error: Error) => {
            if (error) {
                console.error("Something went wrong when connection %s",error.message)
            } else {
                console.log("Successfully connected")
            }
        })

        this._connection.on("error",(error: Error) => {
            if (error) {
                console.error("Something went wrong %s",error.message)
            } else {
                console.log("Successfully connected")
            }
        })

        this._connection.on("infoMessage",(message: InfoObject) => {
            console.log(JSON.stringify(message))
        })

        this._connection.on("errorMessage",(error: Error) => {
            console.log(JSON.stringify(error))
        })


        this._connection.on("debug",(message: string) => {
            console.log(message)
        })

        console.log("Boyakasha")
    }

    public query(request: Request) {
        console.log("Executing query")
        this._connection.execsql(request)
    }
}

(function exec() {
    sqlConnection.create()
})()

我使用 ts-node 运行:

npx ts-node index.ts

然后输出

Creating connection using config
Connection created,creating listeners
Boyakasha

后执行完成,不会触发任何回调。

我还尝试在 Azure Function 运行时运行它,这是最终的预期目标,它也保持活动状态。

我已经通过在运行时运行我的代码来尝试这个:

func start --typescript

在构造函数的末尾我添加一个超时:

setTimeout(() => {
    console.log("Timeout")
},20000)

我选择了 20 000 毫秒,因为 tedious 的认超时时间是 15 000,所以我认为这可能会触发一些错误回调,但可惜,什么都没有。使用 ts-nodefunc start

运行时超时具有相同的行为

在这里错过了什么?根据文档中的 Getting started 部分,感觉应该很简单。

更新 我已经做了一些实验并使用 promise 重写了连接逻辑。这个解决方案会无限期地停止(比应该是认超时值的 15 000 毫秒长):

import { Connection,Request } from "tedious"

export class sqlConnection {

    private static readonly CONNECTION_CONfig: ConnectionConfig = {
        authentication: {
            options: {
                userName: sqlConnection.getEnvironmentvariable("sql_USER_NAME"),password: sqlConnection.getEnvironmentvariable("sql_PASSWORD")
            },server: sqlConnection.getEnvironmentvariable("sql_FQDN"),options: {
            database: sqlConnection.getEnvironmentvariable("sql_DATABASE"),encrypt: true
        }
    }

    private static getEnvironmentvariable(key: string) {
        const value = process.env[key]
        if (value === undefined) {
            throw new Error(`required environment variable ${key} Could not be found`)
        }
        return value
    }

    private _connection: Connection

    /**
     * Creates a new sql connection using environment variables.
     */
    public static async connect() {
        const connection = new sqlConnection()
        console.log("Starting connection")
        await connection.start()
        return connection
    }

    private async start() {
        console.log("Awaiting connection")
        return new Promise<void>((resolve,reject) => {
            this._connection.on("connect",(error: Error) => {
                if (error) {
                    console.log("Error connecting")
                    reject(error)
                }
                console.log("Successfully connected")
                resolve()
            })
        })
    }
    

    private constructor() {
        this._connection = new Connection(sqlConnection.CONNECTION_CONfig)
    }

    public query(request: Request) {
        console.log("Executing query")
        this._connection.execsql(request)
    }
}

(async function exec() {
    await sqlConnection.connect()
})()

解决方法

最近对 API 的更改要求您在连接上调用 connect() 以触发连接尝试。浪费了这么多小时。

https://github.com/tediousjs/tedious/issues/1217

,

这可能对您有所帮助:

https://dev.to/azure/promises-node-tedious-azure-sql-oh-my-ho1

根据我对 node 的最新了解,如果可以,我还建议使用 node-mssql 而不是简单乏味