You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS执行SELECT @@SERVERNAME获取SQL主机名并传递至EJS的实现方案

核心问题修正方案

1. 正确提取SELECT @@SERVERNAME的返回值

当前用字符串硬替换recordset序列化结果的方式鲁棒性极差,只要主机名包含"、}这类特殊字符就会提取失败。
按照mssql库的返回结构,无表头的查询结果,列名默认是空字符串'',因此可以直接从数组索引取值,无需做字符串切割:

  • 查询成功后rec.recordset是长度为1的对象数组,对应查询返回的单行结果
  • 该行对象的空键''存储的就是SQL Server主机名字段值

正确提取代码片段:

request.query('select @@SERVERNAME', (err, rec) => {
  if (err) {
    console.error('查询SQL Server主机名失败:', err)
    return
  }
  // 直接结构化取值,替换原有的字符串replace逻辑
  const sqlServerHostname = rec.recordset[0]['']
  console.log('SQL Server运行节点:', sqlServerHostname)
})

2. 变量存储与EJS传值实现

当前的核心实现痛点是异步回调的作用域时序问题:SQL查询是异步执行的,如果直接在代码顶层定义变量赋值,很容易在变量还没被异步回调赋值时,就被Express路由读取到undefined值。

推荐实现逻辑

  • 在模块顶层定义全局存储对象,分别存两类节点信息:
    • Node.js运行节点主机名:直接用os.hostname()同步获取,无异步延迟
    • SQL Server运行节点主机名:等数据库连接、主机名查询完成后赋值
  • 等待所有节点信息获取完成后,再启动Express服务,从根源上避免时序问题
  • 在页面路由中把存储的两类节点信息作为render参数传给EJS模板

完整可运行的修正代码:

const express = require('express')
const os = require('os')
const mssql = require('mssql')
const dbconfig = require('./src/config/dbconfig.json')

// 初始化站点展示所需的全局数据
const appData = {
  nodeHostname: os.hostname(),
  sqlServerHostname: ''
}

const app = express()
// 配置EJS模板引擎
app.set('view engine', 'ejs')

// 首页路由
app.get('/', (req, res) => {
  res.render('index', {
    nodeHost: appData.nodeHostname,
    sqlHost: appData.sqlServerHostname
  })
})

const pool = new mssql.ConnectionPool(dbconfig)
// 建立数据库连接
pool.connect((err) => {
  if (err) {
    console.log('数据库连接失败:', err)
    process.exit(1)
  }

  const request = new mssql.Request(pool)
  request.query('select @@SERVERNAME', (queryErr, rec) => {
    if (queryErr) {
      console.error('SQL Server主机名查询失败:', queryErr)
      appData.sqlServerHostname = '信息获取失败'
    } else {
      // 结构化提取主机名
      appData.sqlServerHostname = rec.recordset[0]['']
      console.log(`已获取SQL Server节点信息: ${appData.sqlServerHostname}`)
    }

    // 等所有节点信息就绪后再启动服务
    app.listen(3000, () => {
      console.log('演示站点已启动,访问地址: http://localhost:3000')
    })
  })
})

EJS模板展示逻辑

在views/index.ejs文件中直接引用路由传递的变量即可:

<div class="node-info">
  <h3>架构演示:节点部署信息</h3>
  <p>Node.js应用运行节点: <%= nodeHost %></p>
  <p>SQL Server数据库运行节点: <%= sqlHost %></p>
</div>

关键注意事项

  • 不要依赖JSON字符串替换提取数据库返回值,结构化索引取值的可靠性远高于字符串切割,不会受主机名特殊字符影响
  • 不要在异步操作未完成前启动Express服务,否则页面首次加载时会拿到未初始化的空值,不符合K8s演示的展示要求
  • 该方案获取的SQL Server主机名是数据库实例自身的标识,和Node.js本机的主机名完全独立,可以准确区分两个运行节点的信息

内容的提问来源于stack exchange,提问作者Steven com my

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 19:45:04