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.08 的 ODBC 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”错误
C++ 代码 SQLSTATE 中的错误:24000,本机错误:0