Paginate with Sequelize.js at SQL 2008 (that does not support FETCH)

牧云@^-^@ 提交于 2019-12-24 15:27:19

问题


So, I'm using sequelize.js with tediousfor mssql support. MSSQL = SQL Server 2008

Well, So there is this big table named Clientes. I have to fetch data from it, but it is quite huge so I'll have to paginate trhough

I tried the 'right way', as in the docs:

app.use('/clientes', function(req, res){
      var page = req.params.page || 0;
      sequelize.Clientes.findAll({limit: 30, offset: 5  }) 
       .then(function(result) {
      res.json({result: result});
    });
});

It should work, BUT it uses a query that is something like

SELECT .......... from [Clientes] as [Clientes] ORDER BY [CNPJ] OFFSET 5 ROWS FETCH NEXT 30 ROWS ONLY; and the SQL Server return a terrible Invalid usage of the option NEXT in the FETCH statement!

So, after lots of search, I got to a point that apparently FETCH will not work with SQL 2008. That being said (and sad) I tried to force TDS version to 7_3_A. I did this using

dialectOptions: {
      tdsVersion: '7_3_A'
},

but the query sintax did not change with this :(

I'm not sure what to do anymore.... I even will use another way instead of paginate... I found a nice sintax to SQL pagination (involving row_number()) , but I was not able to perform it as a raw query on sequelyze. myModel.query('SQL QUERY HERE') returned undefined function oO'

Any helps will be appreciated


回答1:


Ok, so after lots of searching and debugging, I found 2 things.

1) My sequelize instance was sequelize.sequelize, due to a module.exports with lodash. My bad, I did not remember that, and did not even mention it in the question. I'm sorry about this.

2) The offset and limit do use fetch and thus generates invalid SQL sintax for SQL 2008.

I had to perform a raw query, using sequelize.sequelize.query() (since my instance was sequelize.sequelize).

The query used for pagination in mssql 2008 was found In this answer:

here's my full code, including express routing and ugly format for the query:

var express = require('express')
var app = express();

app.use('/tableName', function(req, res){
    var page = req.params.page || 2;
    var rowsPerPage = req.params.perpage || 30;

    if(rowsPerPage > 100){ 
        rowsPerPage = 100; //this limits how many per page
    }

    var theQuery = 'declare @rowsPerPage as bigint; '+
        'declare @pageNum as bigint;'+
        'set @rowsPerPage='+rowsPerPage+'; '+
        'set @pageNum='+page+';   '+
        'With SQLPaging As   ( '+
        'Select Top(@rowsPerPage * @pageNum) ROW_NUMBER() OVER (ORDER BY ID asc) '+
        'as resultNum, * '+
        'FROM tableName )'+
        'select * from SQLPaging with (nolock) where resultNum > ((@pageNum - 1) * @rowsPerPage);';


    sequelize.sequelize.query(theQuery) 
     .spread(function(result) {
        res.json({result: result});
      });
});

And if you (as I did) wonder why sequelize.sequelize instead of only sequelize?

Well, this is because var sequelize is a require() from a file with the following module.exports:

 module.exports = lodash.extend({
  sequelize: sequelize, //reffers to new Sequelize(db,user,pass,{});
  Sequelize: Sequelize
 }, db)

So this is why just sequelize.query() was returned undefined, and sequelize.sequelize.query() works fine, because in true my sequelize variable is an Object with the sequelize property being the real sequelize connection instance.



来源:https://stackoverflow.com/questions/32762168/paginate-with-sequelize-js-at-sql-2008-that-does-not-support-fetch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!