[英]How to get a MySQL blob as binary data using SQLGetData in C++
I have a MySQL database with a mediumblob
column. 我有一个带有
mediumblob
列的MySQL数据库。 I want to get binary data from the blob field into a C++ stringstream using ODBC on Windows. 我想在Windows上使用ODBC将二进制数据从blob字段转换为C ++字符串流。
I first call SQLDescribeCol
and it indicates that it is of type SQL_LONGVARBINARY
. 我首先调用
SQLDescribeCol
,它指示它的类型为SQL_LONGVARBINARY
。
I then make a call to SQLGetData
as follows: 然后,我如下调用
SQLGetData
:
SQLLEN indicator;
SQLCHAR SqlChar[8000];
SQLGetData(m_sqlstatementhandle, i, SQL_CHAR, &SqlChar, sizeof(SqlChar), (SQLLEN*)&indicator);
I then go on and write the data into a stringstream
: 然后,我继续将数据写入
stringstream
:
stringstream ss;
ss.write((char*)&SqlChar, indicator);
This does give me the blob data, but it is stored in SqlChar
as a HEX string. 这确实给了我Blob数据,但它以十六进制字符串形式存储在
SqlChar
中。
My program expects the data in the stringstream to be stored as binary. 我的程序希望将stringstream中的数据存储为二进制。 Now I could convert the HEX string to binary first and then write it to the stringstream, but that doesn't feel right to me.
现在,我可以先将HEX字符串转换为二进制,然后再将其写入字符串流,但这对我来说不合适。 I would really like to get it as binary straight away from
SQLGetData
. 我真的很想直接从
SQLGetData
以二进制形式获取它。
So a couple of questions: 有几个问题:
SQLGetData
correctly for a blob type? SQLGetData
? SQLCHAR
array the right container to write into? SQLCHAR
数组是要写入的正确容器吗? Thanks. 谢谢。
Supplying SQL_BINARY
as argument is wrong (even if it works here because SQL_BINARY
and SQL_C_BINARY
seems to be defined to the same value). 提供
SQL_BINARY
作为参数是错误的(即使在这里SQL_BINARY
,因为SQL_BINARY
和SQL_C_BINARY
似乎定义为相同的值)。 From the doc of SQLGetData
, about the 3rd argument TargetType
: 从
SQLGetData
的文档中,关于第三个参数TargetType
:
[Input] The type identifier of the C data type of the *TargetValuePtr buffer.
[输入] * TargetValuePtr缓冲区的C数据类型的类型标识符。 For a list of valid C data types and type identifiers, see the C Data Types section in Appendix D: Data Types.
有关有效的C数据类型和类型标识符的列表,请参见附录D:数据类型中的“ C数据类型”部分。
See: https://msdn.microsoft.com/en-us/library/ms715441%28v=vs.85%29.aspx 请参阅: https : //msdn.microsoft.com/zh-cn/library/ms715441%28v=vs.85%29.aspx
The input identifier needs to identify the C-type of the buffer used. 输入标识符需要标识所用缓冲区的C类型。 The c-type identifier are all named something like
SQL_C_foobar
. c类型标识符的名称都类似于
SQL_C_foobar
。
So, you should either pass SQL_C_BINARY
as argument (if you would like to tell the driver to get plain binary data) or SQL_C_CHAR
(if you would like to tell the driver to convert the data to some "character data"). 因此,您应该传递
SQL_C_BINARY
作为参数(如果您想告诉驱动程序获取纯二进制数据)或SQL_C_CHAR
(如果您想告诉驱动程序将数据转换为某些“字符数据”)。 Note that both, SQL_C_CHAR
and SQL_CHAR
, are defined to 1
. 请注意,
SQL_C_CHAR
和SQL_CHAR
都定义为1
。
Some more explanations about your case that the driver converted the data to a "string": As you can see from the list of C Data Types, the buffer-type SQLCHAR
can be used for multiple "C type identifiers": If you use a SQLCHAR
buffer, and pass SQL_C_CHAR
as InputType
, the driver "knows" that the buffer is of type SQLCHAR
and that you would like to get the data as "character data". 关于驱动程序将数据转换为“字符串”的情况的更多说明:从C数据类型的列表中可以看出,缓冲区类型
SQLCHAR
可以用于多个“ C类型标识符”:如果使用SQLCHAR
缓冲区,并将SQL_C_CHAR
作为InputType
传递,驱动程序“知道”该缓冲区的类型为SQLCHAR
,并且您希望将数据作为“字符数据”获取。 So, in your case, MySql will convert the binary data to something human-readable, like a hex-string. 因此,在您的情况下,MySql会将二进制数据转换为人类可读的内容,例如十六进制字符串。 On the other hand, if you pass
SQL_C_BINARY
as InputType
, the driver "knows" that the buffer is of type SQLCHAR
and that you are interested in pure binary values, so there is no need for the driver to convert the binary data to a human-readable string, and it will just fill the buffer with the plain binary data. 另一方面,如果将
SQL_C_BINARY
作为InputType
传递,则驱动程序“知道”缓冲区的类型为SQLCHAR
,并且您对纯二进制值感兴趣,因此不需要驱动程序将二进制数据转换为人类数据。可读的字符串,它将只用纯二进制数据填充缓冲区。
See here for the list of c-types and their corresponding buffer types: https://msdn.microsoft.com/en-us/library/ms714556%28v=vs.85%29.aspx 有关C类型及其对应的缓冲区类型的列表,请参见此处: https : //msdn.microsoft.com/zh-cn/library/ms714556%28v=vs.85%29.aspx
As a general note: Watch out whether the documentation speaks about the "Sql C Type" or the "Sql Type". 作为一般注意事项:请注意文档是讲“ Sql C类型”还是“ Sql类型”。 The first is used to identify the C-type of a buffer, the other is used to identify the logical database type of a column.
第一个用于标识缓冲区的C类型,另一个用于标识列的逻辑数据库类型。
Do you ever spend all day trying to figure something out, and then finally find the answer 20 minutes after posting your question? 您是否一整天都在尝试找出问题,然后在发布问题20分钟后终于找到答案了? I do.
我做。
I noticed on this question that the poster uses SQL_C_BINARY
, which is the same as . SQL_BINARY
我在这个问题上注意到张贴者使用
SQL_C_BINARY
, 它与 。 So when I call SQL_BINARY
相同SQLGetData
as follows I get what I expect. 因此,当我按如下方式调用
SQLGetData
,我得到了期望的结果。
SQLGetData(m_sqlstatementhandle, i, SQL_C_BINARY, &SqlChar, sizeof(SqlChar), (SQLLEN*)&indicator);
So it boiled down to supplying the wrong target type. 因此,归结为提供错误的目标类型。
Edit: Edited to reflect correct information from @erg's post. 编辑:编辑以反映@erg帖子中的正确信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.