Return 来自 SQL 服务器的 C++ 本机客户端中的 NULL 数据类型
Return NULL data types in C++ native client from SQL Server
我正在编写使用 SQL 服务器本机客户端 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
return。
此外,如果您初始化您的缓冲区(例如 char ps[201] = {0};
),那么如果某个字段没有数据 return,您将不会得到垃圾打印输出。
我正在编写使用 SQL 服务器本机客户端 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
return。
此外,如果您初始化您的缓冲区(例如 char ps[201] = {0};
),那么如果某个字段没有数据 return,您将不会得到垃圾打印输出。