Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

C++ GetFieldValue uniqueidentifier

Posted on 2008-10-08
7
Medium Priority
?
1,514 Views
Last Modified: 2013-11-20
I am using VC++ 6.0 and MFC

I select a recordset and then try using GetFieldValue.

This works except for when the field is of type uniqueidentifier (SQL Server 2005)

In that case, the following code fails:

 recset->GetFieldValue(_T("worklist_vuid"), mVar);

It crashes in dbcore.cpp in this function:

void* PASCAL CRecordset::GetDataBuffer(CDBVariant& varValue,

in which it is doing a switch on the field type, and it asserts because, it would seem, uniqueidentifier is not a type of field the MFC class recognizes.

So how do I capture a field value of this type into a CString in my MFC code?

Thanks
0
Comment
Question by:PMH4514
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 19

Expert Comment

by:LordOfPorts
ID: 22673669
I am not certain if this will be helpful however the version of the GetFieldValue function http://msdn.microsoft.com/en-us/library/5f8k59f9(VS.80).aspx you are using has a third optional parameter which by default forces the C data type to be determined based upon the SQL Server data type, try explicitly specifying the third parameter to avoid the automatic determination, according to the documentation SQL_C_CHAR can store any data type and would be worth a try:
recset->GetFieldValue(_T("worklist_vuid"), mVar, SQL_C_CHAR);

Open in new window

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22677713
I googled and found the following statement:

-------------------
The uniqueidentifier data type in SQL Server is stored natively as a 16-byte binary value ...
-------------------

So, you can't read it as string but have to read it as binary and convert manually to a string:

Replace the RFX_Text macro for that field by a RFX_Binary macro like

    RFX_Binary(pFx, _T("worklist_vuid"), m_vuid, 16)

where the m_vuid is a CByteArray member (and not CString).
 
0
 

Author Comment

by:PMH4514
ID: 22678126
itsmeandnobodyelse: - I'm having trouble figuring out how to do what you are saying.
Could you show me a complete code snippet for pulling the uniqueidentifier value out of the field 'worklist_vuid' into a variable I can then use like a CString (ie. for adding it as a label to MFC List controls etc..)

Are you saying something like this I think maybe?

CByteArray bVUID;
recset->GetFieldValue(RFX_Binary(pFx, _T("worklist_vuid"), bVUID, 16), mVar);


but what is pFx ??

Thanks for any clarifications, much appreciated.




0
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
ID: 22679606
>>>> Are you saying something like this I think maybe?

Sorry, I assumed you were using the - generated from wizard - CRecordset::DoFieldExchange which looks like

void CCustSet::DoFieldExchange(CFieldExchange* pFX)
{
   //{{AFX_FIELD_MAP(CCustSet)
   pFX->SetFieldType(CFieldExchange::outputColumn);
   RFX_Text(pFX, "Name", m_strName);
   RFX_Int(pFX, "Age", m_wAge);
   //}}AFX_FIELD_MAP
}

Here the RFX_ macros were used to exchange data from members to recordset or vice versa. If you invoke class wizard (CTRL+W) and choose your CRecordset derived class you should be able to bind your CRecordset to a table of the data source and the wizard would generate the YourSet::DoFieldExchange.

A - less comfortable - alternative to that is calling CRecordset::GetFieldValue yourself  (in the above DoFieldExchange the RFX_ macros have the calls included)

   recset->GetFieldValue(_T("worklist_vuid"), mVar, SQL_C_BINARY);

Then the mVar (a CDBVariant) should contain an array of bytes (unsigned char). Unfortunately, I don't know how to get the bytes from a CDBVariant. But, if you need help for this I could look into the RFX_Binary macro implementation which should have solved that issue.

Note, there should be macros as well which would convert the 16 binary bytes to a GUID string, but unfortunately I don't know much of GUIDs and how to handle them.

0
 

Author Comment

by:PMH4514
ID: 22679764
Thanks.. You also assumed I derived my own CRecordset class. I did not, is this something I must do to accomplish this? Aside from that I saw no need.  I'll explore a bit based on your comments.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22680603
>>>> I did not, is this something I must do to accomplish this?
It is more comfortable. And the wizard will do (nearly) all work for you ...

I found out that the CDBVariant is a union where - depending on type - different members were valid. In case of SQL_C_BINARY data, the m_dwType member of CDBVariant  is set to DBVT_BINARY (what you should check) and the m_pBinary member of the union is valid. The m_pBinary points to a CLongBinary which has a handle to global data - m_hData - and a length member - m_dwDataLength.

I assume there are some macros which would convert a CLongBinary to a CByteArray, but you also could retrieve a pointer to the data by calling GlobalLock. If you output the bytes in the byte  array as hex numbers you should have all digits of the GUID (VUID)  for that record - though not structured. I am sure there are some handy macros which would convert the binary to a string.

0
 

Author Comment

by:PMH4514
ID: 22680999
Interesting, I understand. I think I can get it from here, with the aid of this article I found as well:
http://www.codeguru.com/forum/showthread.php?t=142900

0

Featured Post

Tech or Treat! - Giveaway

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: When running hybrid database environments, you often need to query some data from a remote db of any type, while being connected to your MS SQL Server database. Problems start when you try to combine that with some "user input" pass…
In this article I will describe the Copy Database Wizard method as one possible migration process and I will add the extra tasks needed for an upgrade when and where is applied so it will cover all.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question