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

SQLParamData is not fully compliant with streaming parameters in ODBC 3.8 #133

Open
groprima opened this issue Feb 3, 2023 · 4 comments

Comments

@groprima
Copy link

groprima commented Feb 3, 2023

According to the MS example regarding retrieving Output Parameters with SQLGetData, SQLParamData should be called twice to ensure there is no more streamed parameter data to retrieve. I tested it with MS ODBC drivers 17 and 18 by adding an intermediate state when SQL_PARAM_DATA_AVAILABLE is returned, and it works as expected. The check for the ODBC version also needs to be added (connection_mode >= SQL_OV_ODBC3_80).

else if ( ret == SQL_PARAM_DATA_AVAILABLE  )
{
    if (statement -> state = **STATE_S14_1**) {
        statement -> state = STATE_S14;
    } else {
        statement -> state = **STATE_S14_1**;
    }
}

Microsoft:

https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/retrieving-output-parameters-using-sqlgetdata?view=sql-server-ver16

For each parameter, call SQLBindParameter with InputOutputType set to SQL_PARAM_OUTPUT_STREAM and ParameterValuePtr set to a token, such as a parameter number, a pointer to data, or a pointer to a structure that the application uses to bind input parameters. This example will use the parameter ordinal as the token.

Execute the query with SQLExecDirect or SQLExecute. SQL_PARAM_DATA_AVAILABLE will be returned, indicating that there are streamed output parameters available for retrieval.

Call SQLParamData to get the parameter that is available for retrieval. SQLParamData will return SQL_PARAM_DATA_AVAILABLE with the token of the first available parameter, which is set in SQLBindParameter (step 1). The token is returned in the buffer that the ValuePtrPtr points to.

Call SQLGetData with the argument Col_or_Param_Num set to the parameter ordinal to retrieve the data of the first available parameter. If SQLGetData returns SQL_SUCCESS_WITH_INFO and SQLState 01004 (data truncated), and the type is variable length on both the client and server, there is more data to retrieve from the first available parameter. You can continue to call SQLGetData until it returns SQL_SUCCESS or SQL_SUCCESS_WITH_INFO with a different SQLState.

Repeat step 3 and step 4 to retrieve the current parameter.

Call SQLParamData again. If it returns anything except SQL_PARAM_DATA_AVAILABLE, there is no more streamed parameter data to retrieve, and the return code will be the return code of the next statement that is executed.

Call SQLMoreResults to process the next set of parameters until it returns SQL_NO_DATA. SQLMoreResults will return SQL_NO_DATA in this example if the statement attribute SQL_ATTR_PARAMSET_SIZE was set to 1. Otherwise, SQLMoreResults will return SQL_PARAM_DATA_AVAILABLE to indicate that there are streamed output parameters available for the next set of parameters to retrieve.

@lurcher
Copy link
Owner

lurcher commented Feb 3, 2023 via email

@groprima
Copy link
Author

groprima commented Feb 3, 2023

The only source I could find that defines this behaviour is the MS example above. The MS implementation of the SQL Server driver for macOS and Windows verifies the functionality.

@v-chojas
Copy link
Contributor

v-chojas commented Feb 3, 2023

It's not clear from your initial report and subsequent message that anything is actually wrong --- do you see an error message (and if so, what does it say) where you expected success?

@groprima
Copy link
Author

groprima commented Feb 6, 2023

Sorry, I wasn't clear. If SQLParamData is called a second time, as indicated in item 6 of the MS example, the DM returns the error message:

Msg 0, State HY010, [unixODBC][Driver Manager]Function sequence error

However, if this call is omitted, everything works fine, and correct results are returned. At this point, I suspect a mistake in the MS example.

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

No branches or pull requests

3 participants