c++ - 从 SQL Server 在 C++ native 客户端中返回 NULL 数据类型

标签 c++ sql-server odbc type-conversion sql-server-native-client

我正在编写使用 SQL Server native 客户端 sqlncli.h 的小型 C++ 控制台应用程序 (VS 2013/Windows7)。我在程序中遇到 NULL 字段问题 - 我在输出中看不到正确的值。

#include <windows.h>

#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h> 
#include <sqlncli.h>

#include <cstdio>
#include <string>
#include <iostream>

using namespace std;

int main()
{
    SQLHENV environHandle;
    SQLHDBC connectHandle;
    SQLHSTMT statement; 
    SQLWCHAR* connectString = (SQLWCHAR*)TEXT("Driver={SQL Server};Server=XX.XX.XX.XX;Database=DBNAME;Trusted_Connection=yes;");
    SQLRETURN status;
    status = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environHandle);
    cout << "SQLAllocHandle returned " << status << "\r\n";
    if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS)
    {
        status = SQLSetEnvAttr(environHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, SQL_IS_INTEGER);
        cout << "SQLSetEnvAttr returned " << status << "\r\n";
        if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS)
        {
            status = SQLAllocHandle(SQL_HANDLE_DBC, environHandle, &connectHandle);
            cout << "SQLAllocHandle SQL_HANDLE_DBC returned " << status << "\r\n";
            if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS)
            {
                status = SQLDriverConnect(connectHandle, NULL, connectString, SQL_NTS, NULL, 256, NULL, SQL_DRIVER_NOPROMPT);
                cout << "SQLDriverConnect returned " << status << "\r\n";
                if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS)
                {
                    status = SQLAllocHandle(SQL_HANDLE_STMT, connectHandle, &statement);
                    cout << "SQLAllocHandle SQL_HANDLE_STMT returned " << status << "\r\n";
                    if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS)
                    {
                        status = SQLExecDirect(statement, (SQLWCHAR*)TEXT("SELECT * FROM [DBNAME].[dbo].[Table1]"), SQL_NTS);
                        cout << "SQLExecDirect returned " << status << "\r\n";
                        if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS)
                        {
                            int rec_id;
                            int id;
                            char date[64];
                            char ps[201];
                            while (SQLFetch(statement) == SQL_SUCCESS)
                            {
                                SQLGetData(statement, 1, SQL_C_ULONG, &rec_id, 0, NULL);
                                SQLGetData(statement, 2, SQL_C_ULONG, &id, 0, NULL);
                                SQLGetData(statement, 3, SQL_C_CHAR, date, 64, NULL);
                                SQLGetData(statement, 4, SQL_C_CHAR, ps, 201, NULL);
                                cout << rec_id << " " << id << " " << date << " " << ps << endl;
                            }
                        }
                    }
                    cout << "Connected;"; 
                    cin.get();
                }
            }
        }
    }
    return 0;
}

表1结构:

CREATE TABLE [dbo].[Table1](
    [rec_id] [int] IDENTITY(1,1) NOT NULL,
    [id] [int] NOT NULL,
    [date] [datetime] NOT NULL,
    [ps] [varchar](200) NULL
) ON [PRIMARY]

在控制台输出中,我看到前 3 个字段是正确的,但第四个字段就像 ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ 如何捕获 VARCHAR、NVARCHAR、FLOAT 类型的 NULL 字段?

最佳答案

SQLGetData 函数的最后一个参数是

StrLen_or_IndPtr

[Output] Pointer to the buffer in which to return the length or indicator value. If this is a null pointer, no length or indicator value is returned. This returns an error when the data being fetched is NULL. SQLGetData can return the following values in the length/indicator buffer:

The length of the data available to return
SQL_NO_TOTAL
SQL_NULL_DATA

您目前正在为此传递 NULL,但如果您提供指向有效 SQLLEN 变量的指针,那么您可以检查 SQL_NULL_DATA返回。

此外,如果您初始化您的缓冲区(例如 char ps[201] = {0};),那么如果没有为字段返回数据,您将不会得到垃圾打印输出。

关于c++ - 从 SQL Server 在 C++ native 客户端中返回 NULL 数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29252732/

相关文章:

c# - 一个或多个实体的验证失败。有关源错误 db.SaveChanges() 的更多详细信息,请参阅 'EntityValidationErrors' 属性;

sql - 在 SQL Server 中存储大型数据集的最佳方式?

asp.net - asp.net 的 odbc 连接字符串

c# - SelectCommand.Connection 属性尚未初始化

sql-server-2005 - 为什么我的 SQL Server 审计触发器搞乱了 ODBC 调用/从 Access 刷新?

c++ - API 内存 : Heap or Stack? (C++)

c++ - C中的 "union"和 "struct"之间的主要区别是什么?

c++ - 是否会为非类型模板参数的不同值实例化新类

sql-server - SQL CROSS APPLY 与 SQLCLR 表值函数 (TVF)

c++ - 替代大型数据集的 vector ? C++