2

我正在編寫使用SQL Server本地客戶端sqlncli.h的小型C++控制檯應用程序(VS 2013/Windows7)。我在程序中的NULL字段有問題 - 我看不到正確的值。從SQL Server返回C++本機客戶端中的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字段?

回答

1

SQLGetData函數的最後一個參數是

StrLen_or_IndPtr

[輸出]指向的緩衝器中返回 長度或指示符值。如果這是一個空指針,則不返回任何長度或 指標值。當獲取的數據爲 爲NULL時,將返回錯誤。 SQLGetData可以在 長度/指示器緩衝區返回以下值:

可用數據的長度返回
SQL_NO_TOTAL
SQL_NULL_DATA

您正在傳遞NULL這一點,但如果你提供一個指向有效SQLLEN變量的指針,那麼你可以檢查SQL_NULL_DATA返回。如果你初始化你的緩衝區(例如char ps[201] = {0};),那麼如果沒有數據返回字段,你將不會得到垃圾輸出。

相關問題