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

Node.js中mssql执行触发器SQL报错,Azure Data Studio可正常运行

Node.js中使用mssql ^7.2.0创建触发器的语法错误问题

问题场景

在Node.js项目中使用mssql ^7.2.0库执行创建数据库触发器的SQL语句,该语句在Azure Data Studio中可正常运行,但通过request.query()方法执行时触发语法错误,提示Incorrect syntax near '01'。曾遇到类似问题,怀疑与mssql依赖的Tedious驱动对BEGIN/END关键字的处理有关,但遗忘了解决方案。

执行的SQL语句

CREATE TRIGGER [dbo].[SET_PRODUCT_UPDATE_SAEXIS] ON [dbo].[SAEXIS] AFTER Insert,UPDATE AS

DECLARE @sku VARCHAR(15), @CodUbic VARCHAR(10),  @name VARCHAR(40), @description VARCHAR(40), @categories INT, @regular_price VARCHAR(30), @sale_price VARCHAR(30), @manage_stock INT, @stock_quantity DECIMAL(28,4)

SELECT @sku = Codprod,@Codubic=Codubic FROM inserted
IF @Codubic='01' -- 报错指向此处
BEGIN
    IF EXISTS (Select SKU from TBL_WC_WEB_PRODUCTS_OPERATIONS where operation='P')
    BEGIN
        SELECT @name = name, @description = description, @categories = categories, @regular_price = regular_price, @sale_price = sale_price, @manage_stock = manage_stock, @stock_quantity = stock_quantity
        FROM VW_WC_WEB_PRODUCTS WHERE sku = @sku
        DELETE FROM TBL_WC_WEB_PRODUCTS_OPERATIONS WHERE sku = @sku
        INSERT INTO TBL_WC_WEB_PRODUCTS_OPERATIONS (name, description, sku, categories, regular_price, sale_price, manage_stock, stock_quantity, operation)
        VALUES (@name, @description, @sku, @categories, @regular_price, @sale_price, @manage_stock, @stock_quantity, 'C')
    END
    ELSE
    BEGIN
        SELECT @name = name, @description = description, @categories = categories, @regular_price = regular_price, @sale_price = sale_price, @manage_stock = manage_stock, @stock_quantity = stock_quantity
        FROM VW_WC_WEB_PRODUCTS WHERE sku = @sku
        DELETE FROM TBL_WC_WEB_PRODUCTS_OPERATIONS WHERE sku = @sku
        INSERT INTO TBL_WC_WEB_PRODUCTS_OPERATIONS (name, description, sku, categories, regular_price, sale_price, manage_stock, stock_quantity, operation)
        VALUES (@name, @description, @sku, @categories, @regular_price, @sale_price, @manage_stock, @stock_quantity, 'U')
    END
END

错误日志

RequestError: Incorrect syntax near '01'.
    at handleError (/home/koe/Escritorio/code/work/wc_saint/node_modules/mssql/lib/tedious/request.js:384:15)
    at Connection.emit (node:events:527:28)
    at Connection.emit (/home/koe/Escritorio/code/work/wc_saint/node_modules/tedious/lib/connection.js:1065:18)
    at Parser.<anonymous> (/home/koe/Escritorio/code/work/wc_saint/node_modules/tedious/lib/connection.js:1170:12)
    at Parser.emit (node:events:527:28)
    at Readable.<anonymous> (/home/koe/Escritorio/code/work/wc_saint/node_modules/tedious/lib/token/token-stream-parser.js:27:14)
    at Readable.emit (node:events:527:28)
    at addChunk (/home/koe/Escritorio/code/work/wc_saint/node_modules/readable-stream/lib/_stream_readable.js:298:12)
    at readableAddChunk (/home/koe/Escritorio/code/work/wc_saint/node_modules/readable-stream/lib/_stream_readable.js:280:11)
    at Readable.push (/home/koe/Escritorio/code/work/wc_saint/node_modules/readable-stream/lib/_stream_readable.js:241:10) {
  code: 'EREQUEST',
  originalError: Error: Incorrect syntax near '01'.
      at handleError (/home/koe/Escritorio/code/work/wc_saint/node_modules/mssql/lib/tedious/request.js:382:19)
      at Connection.emit (node:events:527:28)
      at Connection.emit (/home/koe/Escritorio/code/work/wc_saint/node_modules/tedious/lib/connection.js:1065:18)
      at Parser.<anonymous> (/home/koe/Escritorio/code/work/wc_saint/node_modules/tedious/lib/connection.js:1170:12)
      at Parser.emit (node:events:527:28)
      at Readable.<anonymous> (/home/koe/Escritorio/code/work/wc_saint/node_modules/tedious/lib/token/token-stream-parser.js:27:14)
      at Readable.emit (node:events:527:28)
      at addChunk (/home/koe/Escritorio/code/work/wc_saint/node_modules/readable-stream/lib/_stream_readable.js:298:12)
      at readableAddChunk (/home/koe/Escritorio/code/work/wc_saint/node_modules/readable-stream/lib/_stream_readable.js:280:11)
      at Readable.push (/home/koe/Escritorio/code/work/wc_saint/node_modules/readable-stream/lib/_stream_readable.js:241:10) {
    info: ErrorMessageToken {
      name: 'ERROR',
      event: 'errorMessage',
      number: 102,
      state: 1,
      class: 15,
      message: "Incorrect syntax near '01'.",
      serverName: 'garuda',
      procName: 'SET_PRODUCT_CREATE',
      lineNumber: 13
    }
  },
  number: 102,
  lineNumber: 13,
  state: 1,
  class: 15,
  serverName: 'garuda',
  procName: 'SET_PRODUCT_CREATE',
  precedingErrors: []
}

解决方案

该问题确实源于Tedious驱动对多行SQL脚本的解析逻辑,尤其是包含BEGIN/END代码块的语句。以下是几种可行的解决方式:

方法1:启用批处理模式执行

调用request.query()时添加{ batch: true }选项,让驱动以批处理模式执行整个SQL脚本,避免逐行解析导致的语法错误:

await request.query(sqlStatement, { batch: true });

方法2:调整SQL语句换行格式

将SQL语句中的换行符替换为空格,确保IF与BEGIN处于同一逻辑行(此方式会降低SQL可读性,不推荐):

CREATE TRIGGER [dbo].[SET_PRODUCT_UPDATE_SAEXIS] ON [dbo].[SAEXIS] AFTER Insert,UPDATE AS DECLARE @sku VARCHAR(15), @CodUbic VARCHAR(10),  @name VARCHAR(40), @description VARCHAR(40), @categories INT, @regular_price VARCHAR(30), @sale_price VARCHAR(30), @manage_stock INT, @stock_quantity DECIMAL(28,4) SELECT @sku = Codprod,@Codubic=Codubic FROM inserted IF @Codubic='01' BEGIN IF EXISTS (Select SKU from TBL_WC_WEB_PRODUCTS_OPERATIONS where operation='P') BEGIN SELECT @name = name, @description = description, @categories = categories, @regular_price = regular_price, @sale_price = sale_price, @manage_stock = manage_stock, @stock_quantity = stock_quantity FROM VW_WC_WEB_PRODUCTS WHERE sku = @sku DELETE FROM TBL_WC_WEB_PRODUCTS_OPERATIONS WHERE sku = @sku INSERT INTO TBL_WC_WEB_PRODUCTS_OPERATIONS (name, description, sku, categories, regular_price, sale_price, manage_stock, stock_quantity, operation) VALUES (@name, @description, @sku, @categories, @regular_price, @sale_price, @manage_stock, @stock_quantity, 'C') END ELSE BEGIN SELECT @name = name, @description = description, @categories = categories, @regular_price = regular_price, @sale_price = sale_price, @manage_stock = manage_stock, @stock_quantity = stock_quantity FROM VW_WC_WEB_PRODUCTS WHERE sku = @sku DELETE FROM TBL_WC_WEB_PRODUCTS_OPERATIONS WHERE sku = @sku INSERT INTO TBL_WC_WEB_PRODUCTS_OPERATIONS (name, description, sku, categories, regular_price, sale_price, manage_stock, stock_quantity, operation) VALUES (@name, @description, @sku, @categories, @regular_price, @sale_price, @manage_stock, @stock_quantity, 'U') END END

方法3:用存储过程封装触发器创建逻辑

先创建存储过程封装触发器的创建逻辑,再通过mssql调用存储过程,规避驱动解析多行SQL的问题:

CREATE PROCEDURE [dbo].[CreateProductUpdateTrigger]
AS
BEGIN
    SET NOCOUNT ON;
    -- 先删除已存在的同名触发器
    IF EXISTS (SELECT * FROM sys.triggers WHERE name = 'SET_PRODUCT_UPDATE_SAEXIS')
        DROP TRIGGER [dbo].[SET_PRODUCT_UPDATE_SAEXIS];
    
    -- 创建触发器
    CREATE TRIGGER [dbo].[SET_PRODUCT_UPDATE_SAEXIS] ON [dbo].[SAEXIS] AFTER Insert,UPDATE AS
    DECLARE @sku VARCHAR(15), @CodUbic VARCHAR(10),  @name VARCHAR(40), @description VARCHAR(40), @categories INT, @regular_price VARCHAR(30), @sale_price VARCHAR(30), @manage_stock INT, @stock_quantity DECIMAL(28,4)

    SELECT @sku = Codprod,@Codubic=Codubic FROM inserted
    IF @Codubic='01'
    BEGIN
        IF EXISTS (Select SKU from TBL_WC_WEB_PRODUCTS_OPERATIONS where operation='P')
        BEGIN
            SELECT @name = name, @description = description, @categories = categories, @regular_price = regular_price, @sale_price = sale_price, @manage_stock = manage_stock, @stock_quantity = stock_quantity
            FROM VW_WC_WEB_PRODUCTS WHERE sku = @sku
            DELETE FROM TBL_WC_WEB_PRODUCTS_OPERATIONS WHERE sku = @sku
            INSERT INTO TBL_WC_WEB_PRODUCTS_OPERATIONS (name, description, sku, categories, regular_price, sale_price, manage_stock, stock_quantity, operation)
            VALUES (@name, @description, @sku, @categories, @regular_price, @sale_price, @manage_stock, @stock_quantity, 'C')
        END
        ELSE
        BEGIN
            SELECT @name = name, @description = description, @categories = categories, @regular_price = regular_price, @sale_price = sale_price, @manage_stock = manage_stock, @stock_quantity = stock_quantity
            FROM VW_WC_WEB_PRODUCTS WHERE sku = @sku
            DELETE FROM TBL_WC_WEB_PRODUCTS_OPERATIONS WHERE sku = @sku
            INSERT INTO TBL_WC_WEB_PRODUCTS_OPERATIONS (name, description, sku, categories, regular_price, sale_price, manage_stock, stock_quantity, operation)
            VALUES (@name, @description, @sku, @categories, @regular_price, @sale_price, @manage_stock, @stock_quantity, 'U')
        END
    END
END

在Node.js中调用存储过程:

await request.execute('CreateProductUpdateTrigger');

优先推荐方法1,操作简单且不会破坏SQL语句的可读性。


内容的提问来源于stack exchange,提问作者koe255

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:15:41