数据库执行以下语句
    m_Command->CommandText="select convert( UNIQUEIDENTIFIER ,'{33333333-3333-3333-3333-333333333333}') as Guid";
在客户端返回得到的值,希望取得GUID的二进制内容,但是总返回BSTR字符串
VARIANT vtValue = m_Recordset->Fields->GetItem((long)0)->Value;
查了很久,都没有人用到SQL返回GUID类型而需要他二进制值的,他们都只需要显示GUID所以没有解决这个问题。
完整代码如下:// VTEMUN.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")_ConnectionPtr m_Connection; // 数据库连接对象
_RecordsetPtr m_Recordset; // 记录集对象
_CommandPtr m_Command; // 命令对象
const int MAX_CONNECTSTRING_LEN = 255;
char m_szConnectString[MAX_CONNECTSTRING_LEN]; // 数据库连接字符串// 设置数据库连接字符串
BOOL setConnectString(char *szDataSource, char *szDBName, char *szUser, char *szPsw)
{
    if (NULL == szDataSource || NULL == szDBName || NULL == szUser || NULL == szPsw)
    {
        return FALSE;
    }    if (strlen(szDataSource) + strlen(szDBName) + strlen(szUser) + strlen(szPsw) >= MAX_CONNECTSTRING_LEN - 128)
    {
        return FALSE;
    }    memset(m_szConnectString, 0, sizeof(m_szConnectString));    strcpy(m_szConnectString, "Provider=SQLOLEDB;Data Source=");
    strcat(m_szConnectString, szDataSource);
    strcat(m_szConnectString,";Initial Catalog=");
    strcat(m_szConnectString, szDBName);
    strcat(m_szConnectString,";User ID=");
    strcat(m_szConnectString, szUser);
    strcat(m_szConnectString,";Password=");
    strcat(m_szConnectString, szPsw);    return TRUE;
}int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);    if (FAILED(m_Connection.CreateInstance(__uuidof(Connection))))
    {
        return FALSE;
    }    if (FAILED(m_Recordset.CreateInstance(__uuidof(Recordset))))
    {
        return FALSE;
    }    if (FAILED(m_Command.CreateInstance(__uuidof(Command))))
    {
        return FALSE;
    }    setConnectString(".", "master", "sa", "1234");    if (FAILED(m_Connection->Open(m_szConnectString, L"", L"", adConnectUnspecified)))
    {
        return FALSE;
    }    m_Recordset->PutRefSource(m_Command);
    m_Recordset->CursorLocation = adUseClient;    m_Command->ActiveConnection = m_Connection;
    m_Command->CommandType = adCmdText;
    m_Command->CommandText="select convert( UNIQUEIDENTIFIER ,'{33333333-3333-3333-3333-333333333333}') as Guid";    HRESULT hr = m_Recordset->Open((IDispatch*)m_Command, vtMissing, adOpenForwardOnly, adLockReadOnly, adOptionUnspecified);
    _variant_t vtType = m_Recordset->Fields->Item["Guid"]->Type;
// vtType =72,VT_CLSID类型
    VARIANT* vtValue = &(m_Recordset->Fields->GetItem((long)0)->Value);
// 现在得到了GUID值得字符串内容,我希望的是原始的_GUID 值(byte[16])    m_Connection->Close();    if (m_Connection != NULL)
    {
        m_Connection.Release();
        m_Connection = NULL;
    }    if (m_Recordset != NULL)
    {
        m_Recordset.Release();
        m_Recordset = NULL;
    }    if (m_Command != NULL)
    {
        m_Command.Release();
        m_Command = NULL;
    }    CoUninitialize();
    return 0;
}

解决方案 »

  1.   

    查看一下返回的vtValue变量的类型值是多少??
      

  2.   

    _variant_t   vtType   =   m_Recordset-> Fields-> Item["Guid"]-> Type; 
    //   vtType   =72,VT_CLSID类型         VARIANT*   vtValue   =   &(m_Recordset-> Fields-> GetItem((long)0)-> Value); 
    这里就是BSTR了
      

  3.   

    只要格式合法,你可以直接调用一次VariantChangeType强行转换成GUID类型
      

  4.   

    好象不行,转了以后,取出来还是BSTR
    你试过了吗?让我看一下你的代码。
      

  5.   

    基于VARIANT大小的限制,GUID都是以串形式保存的,可以使用UuidFromStringW来转换
      

  6.   

    晕,有这样的限制?GUID形式保存需要16字节,字符串需要32个字符.需要的更多啊
    那么请问大家,VT_CLSID是怎样存取的呢?
      

  7.   

    VARIANT中的union只有8字节,所以无法直接保存GUID,需要用指针的方式代替,最好的替代就是BSTR。因为我没试过,所以仅仅猜测VT_CLSID跟VT_BSTR效果一样。
      

  8.   

    -- 首先要明白,uniqueidentifier 是 16 字节 GUID。 所以可以直接使用 16 进制形式的常量。
    -- 以 GUID 12345678-1234-1234-1234-123456789012(0x78563412123412341234123456789012)select convert(uniqueidentifier, 0x78563412123412341234123456789012) as Guid-- 要使用字符串形式的也可以
    select convert(uniqueidentifier, '12345678-1234-1234-1234-123456789012') as Guid
    select convert(uniqueidentifier, '{12345678-1234-1234-1234-123456789012}') as Guid
    -- 如果你无法直接处理 uniqueidentifier 类型的字段,那可以把 uniqueidentifier 字段转换成 binary(16) 来处理
    select convert(binary(16), convert(uniqueidentifier, 0x78563412123412341234123456789012)) as Bytes
    select convert(binary(16), convert(uniqueidentifier, '12345678-1234-1234-1234-123456789012')) as Bytes
    select convert(binary(16), convert(uniqueidentifier, '{12345678-1234-1234-1234-123456789012}')) as Bytes
    /*
    Guid
    ------------------------------------
    12345678-3412-3412-1234-123456789012(1 行受影响)Guid
    ------------------------------------
    12345678-1234-1234-1234-123456789012(1 行受影响)Guid
    ------------------------------------
    12345678-1234-1234-1234-123456789012(1 行受影响)Bytes
    ----------------------------------
    0x78563412123412341234123456789012(1 行受影响)Bytes
    ----------------------------------
    0x78563412341234121234123456789012(1 行受影响)Bytes
    ----------------------------------
    0x78563412341234121234123456789012(1 行受影响)*/
      

  9.   

    如果你无法直接处理 uniqueidentifier 类型的字段,那可以把 uniqueidentifier 字段转换成 binary(16) 来处理
      

  10.   

    我知道GUID是16个字节, 只是通过ADO记录集字段取到的VARIANT类型时候(m_Recordset->   Fields->   Item["Guid"]),已经变为BSTR类型,我用的时候又要转为字节.
    由于系统操作量大,我们希望优化不必要的转换(GUID->STR->GUID),才提出该问题的.
    现在我们的做法是在数据库返回的时候,转为BINARY类型select ID, NAME, convert(binary(16), GUID) as GUID FROM [USERS]
    这样ADO取到的就是一个SAFEARRAY了,满足我们的业务需要