从 sql 2008 表获取向量

发布于 2024-11-24 03:12:07 字数 3016 浏览 1 评论 0原文

我在 SQL Server 2008 中有一个名为 test 的表,有 6 列和 6 行:

1att  2att  3att  4att  5att  6att 
----------------------------------     
467   116   480   477   491  697  
NULL  219   481   113   488  466  
NULL  NULL  477   466   455  480  
NULL  NULL  NULL  527   483  629  
NULL  NULL  NULL  NULL  483  483  
NULL  NULL  NULL  NULL  NULL 697  

我想要一个包含所有值但具有列顺序的向量。

所以我的矢量看起来像

[ 
    467  116   480   477   491  697    //row 1
    116  219   481   113   488  466    //row 2
    480  481   477   466   455  480    //row 3
    477  113   466   527   483  629    //row 4
    491  488   455   483   483  483    //row 5
    697  466   480   629   483  697    //row 6

 ]

为了做到这一点,我使用 Visual Studio 2008,带有 c++,并使用 ADO 进行连接。

// svd-conn.cpp: archivo de proyecto principal.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
#define MSADO15_PATH "c:\program files\common files\system\ado\msado15.dll"
#ifdef _MSC_VER
    #import MSADO15_PATH rename ("EOF","adoEOF") no_namespace
#else
#define V_INT(X)         V_UNION(X, intVal)
#define V_UINT(X)        V_UNION(X, uintVal)
#include "msado15.tlh"
#endif

#include <comutil.h>

struct InitOle{
     InitOle()  { ::CoInitialize(NULL); }
    ~InitOle() { ::CoUninitialize();   }
} InitOle_tag;

//------------------ utility fns to simplify access to recordset fields
_bstr_t RsItem( _RecordsetPtr p, BSTR fldName ){
    // by field name
    return( p->Fields->Item[_variant_t(fldName)]->Value );
}
_bstr_t RsItem( _RecordsetPtr p, long nIdx ){
    // by field # (0 is first)
    return( p->Fields->Item[_variant_t(nIdx)]->Value );
}
//-------------------------------- The Program ----------------
int main(){
    _RecordsetPtr spRs;
    HRESULT hr;
    _bstr_t sConn= "driver={sql server};SERVER=VIRTUALPC;Database=test;UID=sa; PWD=;";
    _bstr_t sSQL= "SELECT * FROM dbo.test ;";

    try{
        hr= spRs.CreateInstance( __uuidof(Recordset) );
        if FAILED(hr)
            printf("CreateInstance failed\n");
        else
            printf("CreateInstance SUCCESS\n");

        hr= spRs->Open( sSQL, sConn, adOpenForwardOnly, adLockReadOnly, adCmdText );
        if FAILED(hr) 
            printf("Open failed\n");
        else
            printf("Open SUCCESS\n");

        printf("spRs->adoEOF %s\n",spRs->adoEOF);
        while( !(spRs->adoEOF) ) {
            printf("%s\t%s\n",(char*) RsItem( spRs, 0L ),(char*) RsItem( spRs, 1L ),(char*) RsItem( spRs, 2L ) );
            spRs->MoveNext();
        }

        spRs->Close();

    } catch( _com_error &e) {
        printf("Error:%s\n",(char*)e.Description());
    }
    return 0;
}

使用该代码,在 while 循环内我可以获取值,但是如何将它们以正确的方式插入向量中?

那么我如何合并向量类:

vectorv;
并有想要的向量?

我知道要插入向量,我会这样做

v.push_back(467); ....

但是如何以编程方式执行此操作,实际上 NULL 才是真正的问题...

I have a table called test with 6 columns and 6 rows in SQL server 2008:

1att  2att  3att  4att  5att  6att 
----------------------------------     
467   116   480   477   491  697  
NULL  219   481   113   488  466  
NULL  NULL  477   466   455  480  
NULL  NULL  NULL  527   483  629  
NULL  NULL  NULL  NULL  483  483  
NULL  NULL  NULL  NULL  NULL 697  

I would like to have a vector with all values, but with column order.

so my vector would look like

[ 
    467  116   480   477   491  697    //row 1
    116  219   481   113   488  466    //row 2
    480  481   477   466   455  480    //row 3
    477  113   466   527   483  629    //row 4
    491  488   455   483   483  483    //row 5
    697  466   480   629   483  697    //row 6

 ]

To do this I am using Visual Studio 2008,with c++, nd for connecting using ADO.

// svd-conn.cpp: archivo de proyecto principal.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
#define MSADO15_PATH "c:\program files\common files\system\ado\msado15.dll"
#ifdef _MSC_VER
    #import MSADO15_PATH rename ("EOF","adoEOF") no_namespace
#else
#define V_INT(X)         V_UNION(X, intVal)
#define V_UINT(X)        V_UNION(X, uintVal)
#include "msado15.tlh"
#endif

#include <comutil.h>

struct InitOle{
     InitOle()  { ::CoInitialize(NULL); }
    ~InitOle() { ::CoUninitialize();   }
} InitOle_tag;

//------------------ utility fns to simplify access to recordset fields
_bstr_t RsItem( _RecordsetPtr p, BSTR fldName ){
    // by field name
    return( p->Fields->Item[_variant_t(fldName)]->Value );
}
_bstr_t RsItem( _RecordsetPtr p, long nIdx ){
    // by field # (0 is first)
    return( p->Fields->Item[_variant_t(nIdx)]->Value );
}
//-------------------------------- The Program ----------------
int main(){
    _RecordsetPtr spRs;
    HRESULT hr;
    _bstr_t sConn= "driver={sql server};SERVER=VIRTUALPC;Database=test;UID=sa; PWD=;";
    _bstr_t sSQL= "SELECT * FROM dbo.test ;";

    try{
        hr= spRs.CreateInstance( __uuidof(Recordset) );
        if FAILED(hr)
            printf("CreateInstance failed\n");
        else
            printf("CreateInstance SUCCESS\n");

        hr= spRs->Open( sSQL, sConn, adOpenForwardOnly, adLockReadOnly, adCmdText );
        if FAILED(hr) 
            printf("Open failed\n");
        else
            printf("Open SUCCESS\n");

        printf("spRs->adoEOF %s\n",spRs->adoEOF);
        while( !(spRs->adoEOF) ) {
            printf("%s\t%s\n",(char*) RsItem( spRs, 0L ),(char*) RsItem( spRs, 1L ),(char*) RsItem( spRs, 2L ) );
            spRs->MoveNext();
        }

        spRs->Close();

    } catch( _com_error &e) {
        printf("Error:%s\n",(char*)e.Description());
    }
    return 0;
}

with that code, inside the while loop I can get the values, but How could I insert them the right way in the vector?

So How could I incorporate vector class:

vector <double> v;
And have the wished vector??

I know that to insert to vector I do this

v.push_back(467); ....

but how to do it programatically, in fact the NULLS are the real problem...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

马蹄踏│碎落叶 2024-12-01 03:12:07

从问题来看:事实上 NULL 才是真正的问题...
确实是一个相对简单的问题。通过跟踪行和列,并且由于向量是按行顺序填充的,因此可以从其转置位置获取对角线下方单元格的值,即向量中数据的值。
也许类似于以下内容:

#define COLS_PER_ROW 6
int rowNum = 0;
vector <double> v(COLS_PER_ROW * COLS_PER_ROW, 0);     
while( !(spRs->adoEOF) ) {
    for (colNum = 0; colNum < COLS_PER_ROW; colNum++)
    {
       double dVal;
       bstr_t sVal = RsItem(spRs, colNum);
       if (sVal) // this test is equivalent to if (colNum >= rowNum)
       {
           dval = strtod(sVal, NULL);
       }
       else
           dVal = v[colNum * COLS_PER_ROW + rowNum];  // not an error as we want to read the transpose loc for the cell.
    }
    rowNum++;
    spRs->MoveNext();
}

关于空值测试的小注释
if (sVal) 测试数据库提供的值是否为空。
更好的测试可能是
if (colNum >= rowNum) 即假设在下三角形中找到空值,并且与我们在上三角形的“镜像”/“转置”位置获取值一致。

From the question: in fact the NULLS are the real problem...
A relatively simple problem indeed. By keeping track of the row and column, and since the vector is filled-in in row order, the values of the cell below the diagonal can be obtained from their transpose location, i.e. in value of data readily in the vector.
Maybe something like the following:

#define COLS_PER_ROW 6
int rowNum = 0;
vector <double> v(COLS_PER_ROW * COLS_PER_ROW, 0);     
while( !(spRs->adoEOF) ) {
    for (colNum = 0; colNum < COLS_PER_ROW; colNum++)
    {
       double dVal;
       bstr_t sVal = RsItem(spRs, colNum);
       if (sVal) // this test is equivalent to if (colNum >= rowNum)
       {
           dval = strtod(sVal, NULL);
       }
       else
           dVal = v[colNum * COLS_PER_ROW + rowNum];  // not an error as we want to read the transpose loc for the cell.
    }
    rowNum++;
    spRs->MoveNext();
}

A small note on the test for a null value
if (sVal) tests if the database-supplied value was null.
a better test may be
if (colNum >= rowNum) i.e. assuming that the null values are found in the lower triangle, and in agreement with our getting the value in the "mirror"/"transpose" location in the upper triangle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文