SQL 空返回 "stops" 使用 odbc 的 c++ 返回
SQL Null return "stops" return in c++ using odbc
我的表看起来有点像这样
Table cards
| CardId | cityName| eventName| Colour|
|----------+----------+----------+--------|
| 29 | "test" | null | "blue" |
| 2 | null | "test | null |
现在让我们说我做
"select * from card where CardId = 29"
我的返回向量将包含:"测试",仅此而已。因此,它基本上将包含事件名称之前的所有数据。同样的事情也适用于以下内容
"select * from card where CardId = 2"
连接到数据库的C++代码:
void SqlConnection::sqlExecuteSelect(string *select) {
SQLCHAR DBName[20] = "PandemicMain";
SQLCHAR SQLStmt[4000] = { 0 };
SQLRETURN rc = SQL_SUCCESS;
ODBC_Class Example;
if (Example.ConHandle != NULL)
{
rc = SQLConnect(Example.ConHandle, DBName, SQL_NTS, (SQLCHAR *) "concordia", SQL_NTS, (SQLCHAR *) "University4", SQL_NTS);
// Allocate An SQL Statement Handle
rc = SQLAllocHandle(SQL_HANDLE_STMT, Example.ConHandle, &Example.StmtHandle);
rc = SQLExecDirect(Example.StmtHandle, SQLStmt, SQL_NTS);
if (rc == SQL_SUCCESS)
{
// Define A SELECT SQL Statement
char* finalSelect = new char[select->length() + 1];
std::strcpy(finalSelect, select->c_str());
strcpy((char *)SQLStmt, finalSelect);
// Prepare And Execute The SQL Statement
rc = SQLExecDirect(Example.StmtHandle, SQLStmt, SQL_NTS);
// Display The Results Of The SQL Query
if (!rc == SQL_SUCCESS) {
cout << "*************************** failed ***************" << endl;
}
if (rc == SQL_SUCCESS)
{
Example.GetResultset();
Connection.colData = Example.colData;
// At this point you would want to do something
// with the resultset, such as display it.
}
}
// Free The SQL Statement Handle
if (Example.StmtHandle != NULL)
SQLFreeHandle(SQL_HANDLE_STMT, Example.StmtHandle);
// Disconnect From The Northwind Sample Database
rc = SQLDisconnect(Example.ConHandle);
}
}
Odbc.h
#pragma once
////////////////////////////////////////
#include <windows.h>
#include <sql.h>
#include<sqltypes.h>
#include<sqlext.h>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
// Define The ODBC_Class Class
class ODBC_Class
{
struct ColDescription
{
SQLSMALLINT colNumber;
SQLCHAR colName[80];
SQLSMALLINT nameLen;
SQLSMALLINT dataType;
SQLULEN colSize;
SQLSMALLINT decimalDigits;
SQLSMALLINT nullable;
};
// Attributes
public:
SQLHANDLE EnvHandle;
SQLHANDLE ConHandle;
SQLHANDLE StmtHandle;
SQLRETURN rc;
vector<ColDescription> cols;
vector< vector<string> > colData;
// Operations
public:
ODBC_Class(); // Constructor
~ODBC_Class(); // Destructor
SQLRETURN GetResultset();
void DescribeColumns();
private:
_inline SQLRETURN Describe(ColDescription& c);
SQLRETURN GetColData(int colnum, string& str);
};
奥德布.cpp
#include "ODBC.h"
//***************************CODE FROM
http://www.dreamincode.net/forums/topic/127959-odbc-c-example/
*************************************/
// Define The ODBC_Class Class
// Define The Class Constructor
ODBC_Class::ODBC_Class()
{
// Initialize The Return Code Variable
rc = SQL_SUCCESS;
// Allocate An Environment Handle
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvHandle);
// Set The ODBC Application Version To 3.x
if (rc == SQL_SUCCESS)
rc = SQLSetEnvAttr(EnvHandle, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3, SQL_IS_UINTEGER);
// Allocate A Connection Handle
if (rc == SQL_SUCCESS)
rc = SQLAllocHandle(SQL_HANDLE_DBC, EnvHandle, &ConHandle);
}
// Define The Class Destructor
ODBC_Class::~ODBC_Class()
{
// Free The Connection Handle
if (ConHandle != NULL)
SQLFreeHandle(SQL_HANDLE_DBC, ConHandle);
// Free The Environment Handle
if (EnvHandle != NULL)
SQLFreeHandle(SQL_HANDLE_ENV, EnvHandle);
}
// Get the data for one column and return the info in the form
// of a std::string. The ODBC driver will make all necessary
// data conversions from whatever type the data is in the database
// to SQL_CHAR. You could make this function more comples by
// getting the return type as it appears in the database then constructing
// a VARIANT object to hold the data.
SQLRETURN ODBC_Class::GetColData(int colnum, string& str)
{
SQLCHAR buf[255] = { 0 };
if ((rc = SQLGetData(StmtHandle, colnum, SQL_CHAR, buf, sizeof(buf), NULL)) == SQL_SUCCESS)
str = reinterpret_cast<char*>(buf);
return rc;
}
//
// Define The ShowResults() Member Function
SQLRETURN ODBC_Class::GetResultset()
{
// Get all column description
DescribeColumns();
// erase anything that's in the colData vector
colData.clear();
// fetch a row from the resultset
while (SQLFetch(StmtHandle) == SQL_SUCCESS)
{
// vector of strings to hold the column data
vector<string> col;
string data;
// column counter
int i = 1;
// get the data for each column and add it to
// the col vector
while (GetColData(i, data) == SQL_SUCCESS)
{
col.push_back(data);
++i; // increment the column number
}
// add column data to the colData vector
colData.push_back(col);
}
return SQL_SUCCESS;
}
// Get the description for one column in the resultset.
// This was made a seprate function to simplify the coding
SQLRETURN ODBC_Class::Describe(ColDescription& c)
{
return SQLDescribeCol(StmtHandle, c.colNumber,
c.colName, sizeof(c.colName), &c.nameLen,
&c.dataType, &c.colSize, &c.decimalDigits, &c.nullable);
}
// Get the description for all the columns in the resultset.
void ODBC_Class::DescribeColumns()
{
ColDescription c;
c.colNumber = 1;
cols.clear();
while (Describe(c) == SQL_SUCCESS)
{
cols.push_back(c);
++c.colNumber;
}
}
使用 SQLGetDiagRec 之后
我收到以下消息:
Sql状态: 22002
所以我确实知道这意味着"需要但未提供的指示符变量">
无论如何要处理这个?
我有一段时间遇到了完全相同的错误。基本上,ODBC 试图告诉您要检索的值为 NULL。它将使用 SQLGetData(( 中的最后一个参数执行此操作,您可以在此处找到更多信息:https://learn.microsoft.com/en-gb/sql/odbc/reference/syntax/sqlgetdata-function
该行:
if ((rc = SQLGetData(StmtHandle, colnum, SQL_CHAR, buf, sizeof(buf), NULL)) == SQL_SUCCESS)
str = reinterpret_cast<char*>(buf);
您需要将要传入的 NULL 值更改为可以填充的值。这是 ODBC 将尝试填充的缓冲区(如果它是 NULL 值(。它将始终返回您在此字段中返回的列的长度(但如果传递 NULL,则不会下降(,除非它返回 NULL,在这种情况下它需要它。通过 ref 传入 SQLLEN,它应该作为SQL_NULL_DATA返回。
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 从python中调用C++函数并获取返回值
- 矩阵向量乘法(cublasDgemv)返回零
- 为什么模板类中的对象不能返回值