7

我正在使用 Sequelize with Tedious 来访问 SQL Server 2008。

当我这样做时,sequelizeModel.findOne()我得到了这个例外 -

未处理的拒绝 SequelizeDatabaseError:FETCH 语句中选项 NEXT 的使用无效。

我知道 SQL Server 2008 不支持OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY,这就是引发异常的原因。

但我也明确地将tdsVersion繁琐的选项中的7_3_B.

如此处所述 -
http://pekim.github.io/tedious/api-connection.html

我已经尝试了所有 tds 版本,并且生成的查询语法始终包含该FETCH/NEXT语法。

我错过了什么吗?

语法不应该特定于 tds 版本吗?

我还验证了该tdsVersion选项已成功从 sequelize 传递到繁琐的连接库。

生成的查询语法示例 -

SELECT 
    [id], [FIRST_NAME], [LAST_NAME]  
FROM  
    [USERs] AS [USERS] 
ORDER BY 
    [id]  
    OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY;
4

6 回答 6

6

这是 Sequelize 中的一个问题——它使用OFFSET FETCH语法,该语法仅在 SQL Server 2012 和更高版本中受支持。

我在 GitHub 上将此作为问题提交:https ://github.com/sequelize/sequelize/issues/4404

这个问题也会影响findById方法。该方法的一种解决方法是使用findAllawhere来指定 ID,并且只使用返回数组中的第一个元素:

Thing.findAll({
  where: {id: id}
}).then( function(things) {
  if (things.length == 0) {
    // handle error
  }
  doSomething(things[0])
}).catch( function(err) {
  // handle error
});
于 2015-08-28T22:53:04.607 回答
3

检查代码node_modules/sequelize/lib/dialects/mssql/query-generator.js 看到了那部分

const dbVersion = this.sequelize.options.databaseVersion;
const isSQLServer2008 = semver.valid(dbVersion) && semver.lt(dbVersion, '11.0.0');

所以我只是添加了我的连接配置:

production: {
        dialect: 'mssql',
        databaseVersion: '10.50.6000',
        host: process.env.DB_HOST,
        username: process.env.DB_USER,
        password: process.env.DB_PASS,
        database: process.env.DB_NAME,
        dialectOptions: {
            options: {
                useUTC: false,
                dateFirst: 1,
                enableArithAbort: true,
                encrypt: false,
            },
        },
    },

于 2020-07-24T18:28:57.560 回答
2

我在使用 sequelize v4.42.0 和 SQL Server 2008 R2 (SP1) 时遇到了同样的问题。检查 SequelizeJS 的源代码,我在文件 lib/dialects/mssql/query-generator.js 中发现您在该版本的第 821 行有 selectFromTableFragment 函数。在 826 行中存在一个 if 语句,该语句通过 Sequelize 选项对象中的 databaseVersion 选项验证 SQL Server 的版本号。

// Handle SQL Server 2008 with TOP instead of LIMIT
if (semver.valid(this.sequelize.options.databaseVersion) && semver.lt(this.sequelize.options.databaseVersion, '11.0.0')) {

http://docs.sequelizejs.com的文档中不存在此选项,我搜索了此选​​项但没有找到。在这个选项中,我设置了我的 SQL Server 版本号('10.50.2500' - 相当于 2008 R2 SP1),这确实有效。现在查询是使用 SELECT TOP ... 而不是 OFFSET AND FETCH NEXT 创建的。

我希望这可以帮助像我一样遇到这个问题的其他人。

于 2019-01-02T18:34:35.617 回答
1

如果您可以更改节点模块中的 sequelize 库。请按照以下步骤操作:转到 Node_modules -> sequelize -> lib -> mssql -> query-generator.js

你会发现这一行:

    fragment += ` OFFSET ${this.escape(offset)} ROWS`;

在它上面添加一行:

    fragment += ` ORDER BY ${this.quoteTable(options.tableAs || model.name)}.${this.quoteIdentifier(model.primaryKeyField)}`;

这应该看起来像:

    fragment += ` ORDER BY ${this.quoteTable(options.tableAs || model.name)}.${this.quoteIdentifier(model.primaryKeyField)}`;

    fragment += ` OFFSET ${this.escape(offset)} ROWS`;
于 2018-01-01T13:51:35.217 回答
1

在初始化后立即执行“sequelize.authenticate”方法可以解决我的问题。我不知道这里发生了什么,但是,我遇到了同样的错误。

SequelizeDatabaseError: Invalid usage of the option NEXT in the FETCH statement.
    at Query.formatError (C:\xampp\htdocs\Benoit\node_modules\sequelize\lib\dialects\mssql\query.js:315:12)
    at Request.connection.lib.Request [as userCallback] (C:\xampp\htdocs\Benoit\node_modules\sequelize\lib\dialects\mssql\query.js:107:25)
    at Request._this.callback (C:\xampp\htdocs\Benoit\node_modules\tedious\lib\request.js:60:27)
    at Connection.endOfMessageMarkerReceived (C:\xampp\htdocs\Benoit\node_modules\tedious\lib\connection.js:1922:20)
    at Connection.dispatchEvent (C:\xampp\htdocs\Benoit\node_modules\tedious\lib\connection.js:1004:38)
    at Parser.<anonymous> (C:\xampp\htdocs\Benoit\node_modules\tedious\lib\connection.js:805:18)
    at emitOne (events.js:116:13)
    at Parser.emit (events.js:211:7)
    at Parser.<anonymous> (C:\xampp\htdocs\Benoit\node_modules\tedious\lib\token\token-stream-parser.js:54:15)
    at emitOne (events.js:116:13)
    at Parser.emit (events.js:211:7)
    at addChunk (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_readable.js:291:12)
    at readableAddChunk (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_readable.js:278:11)
    at Parser.Readable.push (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_readable.js:245:10)
    at Parser.Transform.push (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_transform.js:148:32)
    at Parser.afterTransform (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_transform.js:91:10)
    at Parser._transform (C:\xampp\htdocs\Benoit\node_modules\tedious\lib\token\stream-parser.js:69:9)
    at Parser.Transform._read (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_transform.js:184:10)
    at Parser.Transform._write (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_transform.js:172:83)
    at doWrite (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_writable.js:428:64)
    at writeOrBuffer (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_writable.js:417:5)
    at Parser.Writable.write (C:\xampp\htdocs\Benoit\node_modules\readable-stream\lib\_stream_writable.js:334:11)

在一个项目中对我的代码进行了简短的重组后,我得到了错误,我意识到,仅仅因为我的 sublime 的历史存储了它,我只是删除了项目中所有多余的代码,并且对经过身份验证的方法进行了注释。

我不知道初始身份验证方法与查询的语法和句法之间是什么关系,我什至不认为一定有关系,但它是什么

于 2018-08-07T19:50:55.287 回答
0

我正在使用select @@version->

Microsoft SQL Server 2014 - 12.0.2000.8 (X64) 
    Feb 20 2014 20:04:26 
    Copyright (c) Microsoft Corporation
    Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 17134: ) (Hypervisor)

并得到同样的错误。 sequelize.authenticate()没有修复它。

另见:https ://github.com/tediousjs/tedious/issues/872

对我来说,根本原因。基本上,您需要一个 ORDER BY 才能使 OFFSET 有意义。上面的@prayag 答案添加了 ORDER BY。

于 2019-02-23T01:16:43.200 回答