C 中的 SQLExecDirect 结果 -1 状态 24000

Posted

技术标签:

【中文标题】C 中的 SQLExecDirect 结果 -1 状态 24000【英文标题】:SQLExecDirect result -1 state 24000 in C 【发布时间】:2015-11-02 08:25:51 【问题描述】:

你好,我正在学习 C 和 ODBC 调用 SQLExecDirect 函数时出现错误。 请帮我 这是代码

#include <Windows.h>
#include <sql.h>
#include <sqlext.h>

int main( void )

    //DB connect example
    SQLRETURN   nResult     = 0;
    SQLHANDLE   handleEnv   = 0;
    nResult = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, ( SQLHANDLE* )&handleEnv );
    //nResult = SQLSetEnvAttr( handleEnv, SQL_ATTR_ODBC_VERSION, ( SQLPOINTER )SQL_OV_ODBC2, SQL_IS_INTEGER );
    nResult = SQLSetEnvAttr( handleEnv, SQL_ATTR_ODBC_VERSION, ( SQLPOINTER )SQL_OV_ODBC3, SQL_IS_INTEGER );
    nResult = SQLSetEnvAttr( handleEnv, SQL_ATTR_CONNECTION_POOLING, (SQLPOINTER)SQL_CP_ONE_PER_HENV, SQL_IS_INTEGER);

    SQLHANDLE   handleDBC   = 0;
    nResult = SQLAllocHandle( SQL_HANDLE_DBC, handleEnv, ( SQLHANDLE* )&handleDBC );

    SQLCHAR     strConnect[ 256 ]       = "DSN=MY TEST DB; UID=TESTsa; PWD=TESTpw";
    SQLCHAR     strConnectOut[ 1024 ]   = 0;
    SQLSMALLINT nNumOut                 = 0;
    nResult = SQLDriverConnect( handleDBC, NULL, ( SQLCHAR* )strConnect, SQL_NTS, ( SQLCHAR* )strConnectOut, sizeof(strConnectOut),
                                &nNumOut, SQL_DRIVER_NOPROMPT );

    SQLHSTMT    handleStatement = 0;
    //nResult = ::SQLAllocStmt( handleDBC, &handleStatement );
    nResult = SQLAllocHandle( SQL_HANDLE_STMT, handleDBC, ( SQLHANDLE* )&handleStatement );

    SQLHSTMT    hstmt       = handleStatement;
    int         sqlResultOutput = 0;

    SQLINTEGER  cbValue     = 0;
    nResult = SQLBindParameter( hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG,    SQL_INTEGER,    0, 0, &sqlResultOutput,  0, &cbValue );

    //here is the problem
    nResult = SQLExecDirect( hstmt, (SQLTCHAR*) "CALL my_TEST_SP(?)", SQL_NTS );
    //nResult Value is -1 and SQL State is 24000

    return 0;

每次通话结果都很好。只返回一个 SQL_SUCCESS SQLExecDirect 函数返回 -1,SQLState 为 24000

存储过程就这么简单

CREATE PROCEDURE my_TEST_SP
 @retValue int = 0 output
AS
BEGIN
   SET NOCOUNT ON

   SET @retValue = 0

   SELECT myTestCol
   FROM tTestTable

   IF @@ERROR <> 0
   BEGIN
     SET @retValue = -1
   END
END

我的操作系统是 windows7。 使用 Visual Studio 2010 sp1、sqlserver 2012

我想念什么?请告诉我,祝你有美好的一天:)

【问题讨论】:

***.com/questions/3727907/…的可能重复 对不起,我检查了,但我不明白。但感谢您的评论 令人困惑的是,我可以在 Windows 7 上使用“ODBC Driver 11 for SQL Server”和 Visual Studio 2013 对 sql server 2014 运行这个稍作修改的代码(连接字符串,使用 SQLWCHAR)。 我的操作系统是 windows7 64bit,syswow64 中的 ODBC 驱动程序是 SQL Server 版本 6.01.7601.1744,SQL Server Native Client 11.1 版本 2011.110.2100.60 system32 文件夹中的驱动程序是相同的。无论如何我都会更改代码并使用 SQLWCHAR 重试 我将 SQLCHAR 更改为 SQLWCHAR,添加 L 以转发 reteral 字符串并使用 DriverConnectW、ExecDirectW 所以重试购买仍然 SQLExecDirectW 返回 -1 另一个函数返回零(SQL_SUCCESS)我认为可能是它的 visial studio 2010 问题因为我只是通过创建新的解决方案和项目(调试模式)在该代码上运行,但结果相同 【参考方案1】:

主要区别似乎是 odbc 驱动程序版本。我的版本是2014.120.2000.08。我不认为这是由于不同的视觉工作室版本 - 我认为他们都使用相同的 odbc32.lib 在引擎盖下。

以下代码对我有用:我更改了存储过程以返回不为 0 的内容(以验证我是否可以实际读取返回的数据):

 @retValue int = 0 output
AS
BEGIN
   SET NOCOUNT ON

   SET @retValue = 3499

   SELECT myTestCol
   FROM tTestTable

   IF @@ERROR <> 0
   BEGIN
     SET @retValue = -1
   END
END

我在 Visual Studio 2013 中使用了以下代码:

void printErrDbc(SQLHDBC hDbc)

    SQLSMALLINT recNr = 1;
    SQLRETURN ret = SQL_SUCCESS;
    while (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
    
        SQLWCHAR errMsg[SQL_MAX_MESSAGE_LENGTH + 1];
        SQLWCHAR sqlState[5 + 1];
        errMsg[0] = 0;
        SQLINTEGER nativeError;
        SQLSMALLINT cb = 0;
        ret = SQLGetDiagRec(SQL_HANDLE_DBC, hDbc, recNr, sqlState, &nativeError, errMsg, SQL_MAX_MESSAGE_LENGTH + 1, &cb);
        if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
        
            std::wcerr << L"ERROR; native: " << nativeError << L"; state: " << sqlState << L"; msg: " << errMsg << std::endl;
        
        ++recNr;
    


void printErrStmt(SQLHSTMT hStmt)

    SQLSMALLINT recNr = 1;
    SQLRETURN ret = SQL_SUCCESS;
    while (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
    
        SQLWCHAR errMsg[SQL_MAX_MESSAGE_LENGTH + 1];
        SQLWCHAR sqlState[5 + 1];
        errMsg[0] = 0;
        SQLINTEGER nativeError;
        SQLSMALLINT cb = 0;
        ret = SQLGetDiagRec(SQL_HANDLE_STMT, hStmt, recNr, sqlState, &nativeError, errMsg, SQL_MAX_MESSAGE_LENGTH + 1, &cb);
        if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
        
            std::wcerr << L"ERROR; native: " << nativeError << L"; state: " << sqlState << L"; msg: " << errMsg << std::endl;
        
        ++recNr;
    


int _tmain(int argc, _TCHAR* argv[])

    //DB connect example
    SQLRETURN   nResult = 0;
    SQLHANDLE   handleEnv = 0;
    nResult = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, (SQLHANDLE*)&handleEnv);
    //nResult = SQLSetEnvAttr( handleEnv, SQL_ATTR_ODBC_VERSION, ( SQLPOINTER )SQL_OV_ODBC2, SQL_IS_INTEGER );
    nResult = SQLSetEnvAttr(handleEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
    nResult = SQLSetEnvAttr(handleEnv, SQL_ATTR_CONNECTION_POOLING, (SQLPOINTER)SQL_CP_ONE_PER_HENV, SQL_IS_INTEGER);

    SQLHANDLE   handleDBC = 0;
    nResult = SQLAllocHandle(SQL_HANDLE_DBC, handleEnv, (SQLHANDLE*)&handleDBC);

    SQLWCHAR     strConnect[256] = L"DSN=test;UID=sa;PWD=MySecretPassword";
    SQLWCHAR     strConnectOut[1024] =  0 ;
    SQLSMALLINT nNumOut = 0;
    nResult = SQLDriverConnect(handleDBC, NULL, (SQLWCHAR*)strConnect, SQL_NTS, (SQLWCHAR*)strConnectOut, sizeof(strConnectOut),
        &nNumOut, SQL_DRIVER_NOPROMPT);
    if (!SQL_SUCCEEDED(nResult))
    
        printErrDbc(handleDBC);
    

    SQLHSTMT    handleStatement = 0;
    //nResult = ::SQLAllocStmt( handleDBC, &handleStatement );
    nResult = SQLAllocHandle(SQL_HANDLE_STMT, handleDBC, (SQLHANDLE*)&handleStatement);

    SQLHSTMT    hstmt = handleStatement;
    int         sqlResultOutput = 0;

    SQLINTEGER  cbValue = 0;
    nResult = SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &sqlResultOutput, 0, &cbValue);

    //here is the problem
    nResult = SQLExecDirect(hstmt, (SQLWCHAR*)L"CALL my_TEST_SP(?)", SQL_NTS);
    if (!SQL_SUCCEEDED(nResult))
    
        printErrStmt(hstmt);
    
    nResult = SQLMoreResults(hstmt);
    if (!(SQL_SUCCEEDED(nResult) || nResult == SQL_NO_DATA))
    
        printErrStmt(hstmt);
    
    std::wcout << L"Value of sqlResultOutput is: " << sqlResultOutput << std::endl;

    return 0;

在 ODBC 数据源管理器中,我使用版本 2014.120.2000.08ODBC Driver 11 for SQL Server 创建了一个名为 test 的相应 DSN。最后,DSN 条目显示以下属性(在您可以点击Test Data Source... 的对话框中):

Microsoft ODBC Driver for SQL Server Version 12.00.2000

Data Source Name: test
Data Source Description: 
Server: .\SQLSERVERINSTANCE
Use Integrated Security: Yes
Database: Test
Language: (Default)
Data Encryption: No
Trust Server Certificate: No
Multiple Active Result Sets(MARS): No
Mirror Server: 
Translate Character Data: Yes
Log Long Running Queries: No
Log Driver Statistics: No
Use Regional Settings: No
Use ANSI Quoted Identifiers: Yes
Use ANSI Null, Paddings and Warnings: Yes

如果我运行这个示例应用程序,我会得到预期的输出:

Value of sqlResultOutput is: 3499

所以我建议您尝试使用最新的 ODBC Driver for SQL Server。我想是这里下载:http://www.microsoft.com/de-ch/download/details.aspx?id=36434

【讨论】:

感谢您的回答我只是下载 msodbcsql.msi 并通过链接安装它但 ODBC 驱动程序版本没有改变奇怪它仍然开始 2011 年而不是 2014 年即使我卸载 ODBC 驱动程序并重用 msodbcsql.msi 文件生病保留尝试设置 odbc 驱动程序版本 2014 我找不到 2014 版 odbc 驱动程序。只有我能找到 2011 不知道为什么。可能是我需要 VS2013 或 SQLserver2014 太伤心了。但谢谢你的回答,呃 是的,您可以尝试使用 Sql Server 2014。我一直在使用 SQL Server 2014 Express Edition 进行测试(可以从 microsoft 免费下载)。希望这会有所帮助,祝你好运。 今天我将 SQL ServerManagement 2014 ExpressEdition 设置为运行问题代码 PC(不是数据库 PC)并检查“SQL Server 2014.120.2000.08 的 ODBC 驱动程序 11”是否已安装。所以我再次重试。但我仍然得到相同的结果。只有 SQLExecDirect 函数返回 -1 也许我需要 DBMS pc 的 ODBC 驱动程序更新,但它的共享 pc,不仅我使用。因此,我没有尝试过……谢谢尔格 :) 祝你有美好的一天

以上是关于C 中的 SQLExecDirect 结果 -1 状态 24000的主要内容,如果未能解决你的问题,请参考以下文章

无法从 R 查询 Oracle 表 - “Could not SQLExecDirect”错误

在SQL语句中使用变量

C++ 代码 SQLSTATE 中的错误:24000,本机错误:0

如何在 RODBC 中运行 SQL 更新语句?

为啥 mingw bin 目录中的 c++fit 无法返回预期结果?

C中的算术级数不是正确的结果[重复]