Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Prepared statement with cursor does not return result in second call with new bind. #330

Open
ErikJansenIRefact opened this issue Apr 24, 2023 · 6 comments

Comments

@ErikJansenIRefact
Copy link

Describe your system

  • odbc Package Version: 2.4.7
  • ODBC Driver: Microsoft ODBC Driver V18
  • Database Name: SQLServer
  • Database Version: 2019
  • Database OS: Windows
  • Node.js Version: 16.15.1
  • Node.js OS: Mac Ventura 13.3

Describe the bug
A prepared statement is created (a query) with a single parameter together with a bind for it's value.
The prepared statement is executed as a cursor and an expected result is returned after which the cursor is closed.

A new bind value is passed to the statement and again the statement is executed as a cursor.
In the second execute a result was expected but nothing was returned.

Expected behavior

  1. A query result in the first call.
  2. A query result in the second call.

To Reproduce

  1. create a simple test table and populate with 2 rows: CREATE TABLE test (id int); insert into test values (1), (2);
  2. Execute the code as given below

Code

const odbc = require('odbc');

async function connectToDatabase() {
    const connectionConfig = {
        connectionString: 'DSN=MSSQL2019;uid=sa;pwd=iRefact2017;MARS_Connection=no;trustServerCertificate=yes',
        connectionTimeout: 10,
        loginTimeout: 10
    };

    const connection = await odbc.connect(connectionConfig);
    const statement = await connection.createStatement();
    await statement.prepare(`
    select * from IR_TSTGIN.dbo.test where id = ?;
    `);
    await statement.bind([1]);

    let cursor = await statement.execute({
        fetchSize: 1
    });
    while (!cursor.noData) {
        const result = await cursor.fetch();
        console.dir(result, {
            depth: null
        });
    }
    await cursor.close();

    await statement.bind([2]);

    cursor = await statement.execute({
        fetchSize: 1
    });
    while (!cursor.noData) {
        const result = await cursor.fetch();
        console.dir(result, {
            depth: null
        });
    }
    await cursor.close();

}

connectToDatabase()
    .catch(error => {
        console.dir(error, {
            depth: null
        });
    });

Additional context

The logging of the result returned reveals something interesting: the value of the parameters property in the second execution reports a value [1] where a value 2 was bound. Nevertheless the query does not report a result (if the parameter would have had value 1 it still should have returned a record).

This is the console.log of the result object for the first and second statement:

First statement:

[
  { id: 1 },
  statement: '\n    select * from IR_TSTGIN.dbo.test where id = ?;\n    ',
  parameters: [ 1 ],
  return: undefined,
  count: -1,
  columns: [
    {
      name: 'id',
      dataType: 4,
      columnSize: 10,
      decimalDigits: 0,
      nullable: true
    }
  ]
]

Second statement:

[
  statement: '\n    select * from IR_TSTGIN.dbo.test where id = ?;\n    ',
  parameters: [ 1 ],
  return: undefined,
  count: -1,
  columns: [
    {
      name: 'id',
      dataType: 4,
      columnSize: 10,
      decimalDigits: 0,
      nullable: true
    }
  ]
]
@stale
Copy link

stale bot commented May 24, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale This issue hasn't seen any interaction in 30 days. label May 24, 2023
@ErikJansenIRefact
Copy link
Author

Please do not close.

@stale stale bot removed the stale This issue hasn't seen any interaction in 30 days. label May 25, 2023
@stale
Copy link

stale bot commented Jun 24, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale This issue hasn't seen any interaction in 30 days. label Jun 24, 2023
@ErikJansenIRefact
Copy link
Author

Do not close.

@stale stale bot closed this as completed Jul 9, 2023
@ErikJansenIRefact
Copy link
Author

Please re-open.

@markdirish markdirish added confirmed and removed stale This issue hasn't seen any interaction in 30 days. labels Jul 11, 2023
@markdirish markdirish reopened this Jul 11, 2023
@FredoMartini
Copy link

Hello,

I encountered the same problem.
A temporary solution would be to ignore noData and check the return of fetch().

So, this code :

    while (!cursor.noData) {
        const result = await cursor.fetch();
        
        // use result here
    }

can be written like this :

    while(true) {
        const result = await cursor.fetch();
        if (result.length === 0) {
            break;
        }
        // use result here
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants