首页 文章

Tedious或Sequelize使用`findOne()`的错误语法

提问于
浏览
5

我正在使用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;

5 回答

  • 0

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

    我在GitHub上提交了这个问题:https://github.com/sequelize/sequelize/issues/4404

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

    Thing.findAll({
      where: {id: id}
    }).then( function(things) {
      if (things.length == 0) {
        // handle error
      }
      doSomething(things[0])
    }).catch( function(err) {
      // handle error
    });
    
  • 0

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

    你会发现这一行:

    fragment ='OFFSET'his.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'his.escape(offset)'ROWS';

  • 0

    在初始化之后立即执行“sequeIize.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的历史记录存储了它,我只是删除了项目中的所有多余代码,并对经过身份验证的方法进行了评论 .

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

  • 5

    我使用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创建查询 .

    我希望这有助于其他像我一样有这个问题的人 .

  • 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

    对我来说,root cause . 基本上,你需要一个ORDER BY来使OFFSET有意义 . 上面的@prayag回答补充说ORDER BY .

相关问题