Dela via


Postuppsättning: Dynamiskt bindande datakolumner (ODBC)

Det här avsnittet gäller för MFC ODBC-klasserna.

Postuppsättningar hanterar bindningstabellkolumner som du anger vid designtillfället, men det finns fall då du kanske vill binda kolumner som var okända för dig vid designtillfället. I det här avsnittet förklaras:

Anmärkning

Det här avsnittet gäller för objekt som härleds från CRecordset där massradhämtning inte har implementerats. I allmänhet rekommenderas inte de tekniker som beskrivs om du använder massradhämtning. Mer information om masshämtning av rader finns i Recordset: Fetching Records in Bulk (ODBC).

När du kan binda kolumner dynamiskt

Anmärkning

MFC ODBC-konsumentguiden är inte tillgänglig i Visual Studio 2019 och senare. Du kan fortfarande skapa en konsument manuellt.

Vid designtillfället skapar MFC-programguiden eller MFC ODBC-konsumentguiden (från Lägg till klass) postuppsättningsklasser baserat på kända tabeller och kolumner i datakällan. Databaser kan ändras från när du utformar dem och senare när din applikation använder tabellerna och kolumnerna vid körningstid. Du eller en annan användare kan lägga till eller släppa en tabell eller lägga till eller släppa kolumner från en tabell som programmets postuppsättning förlitar sig på. Detta är förmodligen inte ett problem för alla dataåtkomstprogram, men om det är för ditt, hur kan du hantera ändringar i databasschemat, förutom genom att omdesigna och kompilera om? Syftet med det här ämnet är att besvara den frågan.

Det här avsnittet beskriver det vanligaste fallet där du kan binda kolumner dynamiskt – när du har börjat med en postuppsättning baserad på ett känt databasschema och vill hantera ytterligare kolumner vid drifttid. Ämnet förutsätter vidare att de ytterligare kolumnerna mappas till CString fältdatamedlemmar, det vanligaste fallet, även om förslag ges som hjälper dig att hantera andra datatyper.

Med en liten mängd extra kod kan du:

Postuppsättningen innehåller fortfarande datamedlemmar för de kolumner som du kände till vid designtillfället. Den innehåller också en liten mängd extra kod som dynamiskt avgör om några nya kolumner har lagts till i din måltabell och, i så fall, binder dessa nya kolumner till lagring som allokerats dynamiskt (i stället för till rekordsatsens datamedlemmar).

Det här avsnittet omfattar inte andra dynamiska bindningsfall, till exempel borttagna tabeller eller kolumner. I dessa fall måste du använda ODBC API-anrop mer direkt. Mer information finns i ODBC-programmerarens referens.

Så här binder du kolumner dynamiskt

Om du vill binda kolumner dynamiskt måste du känna till (eller kunna fastställa) namnen på de ytterligare kolumnerna. Du måste också allokera lagring för de ytterligare fältdatamedlemmarna, ange deras namn och deras typer och ange antalet kolumner som du lägger till.

Följande diskussion nämner två olika dataposter. Den första är huvudpostuppsättningen som väljer poster från måltabellen. Den andra är en speciell uppsättning kolumnposter som används för att hämta information om kolumnerna i måltabellen.

Allmän process

På den mest allmänna nivån följer du dessa steg:

  1. Utforma huvudobjektet för datauppsättningen.

    Du kan valfritt skicka en pekare till ett öppet CDatabase-objekt eller på något annat sätt tillhandahålla anslutningsinformation till kolumnpostuppsättningen.

  2. Vidta åtgärder för att lägga till kolumner dynamiskt.

    Se processen som beskrivs i Lägga till kolumnerna nedan.

  3. Öppna huvudpostuppsättningen.

    Postuppsättningen väljer poster och använder record field exchange (RFX) för att binda både de statiska kolumnerna (de som mappas till postuppsättningens fältdataelement) och de dynamiska kolumnerna (mappade till extraförvaring som du själv allokerar).

Lägga till kolumnerna

Dynamisk bindning av tillagda kolumner under körning kräver följande steg:

  1. Bestäm vid körning vilka kolumner som finns i måltabellen. Extrahera från den informationen en lista över de kolumner som har lagts till i tabellen sedan din recordset-klass utformades.

    En bra metod är att använda en kolumnpostuppsättningsklass som är utformad för att fråga datakällan efter kolumninformation för måltabellen (till exempel kolumnnamn och datatyp).

  2. Ange lagring för de nya fältdatamedlemmarna. Eftersom din huvudsakliga postuppsättningsklass inte har fältdatamedlemmar för okända kolumner måste du ange en plats där du kan lagra namn, resultatvärden och eventuellt information om datatyp (om kolumnerna är olika datatyper).

    En metod är att skapa en eller flera dynamiska listor, en för de nya kolumnernas namn, en annan för deras resultatvärden och en tredje för deras datatyper (om det behövs). Dessa listor, särskilt värdelistan, innehåller information och nödvändig lagring för bindning. Följande bild visar hur du skapar listorna.

    Skapa listor med kolumner som ska bindas dynamiskt.
    Skapa listor över kolumner som ska bindas dynamiskt

  3. Lägg till ett RFX-funktionsanrop i huvudpostuppsättningens DoFieldExchange funktion för varje tillagd kolumn. Dessa RFX-anrop hämtar en post, inklusive eventuella extra kolumner, och binder kolumnerna till datamedlemmar i postuppsättningen eller till din dynamiska lagring.

    En metod är att lägga till en loop till huvudpostuppsättningens DoFieldExchange funktion som loopar igenom listan med nya kolumner och anropar lämplig RFX-funktion för varje kolumn i listan. Vid varje RFX-anrop skickar du ett kolumnnamn från kolumnnamnslistan och anger en lagringsplats i den motsvarande medlemmen i resultatvärdeslistan.

Listor med kolumner

De fyra listor som du behöver arbeta med visas i följande tabell.

Lista Beskrivning
Aktuella tabellkolumner (Lista 1 i bilden) En lista över kolumnerna som för närvarande finns i tabellen på datakällan. Den här listan kan stämma överens med listan över kolumner som just nu är bundna i din postuppsättning.
Bound-Recordset-Columns (Lista 2 i bilden) En lista över kolumnerna som är bundna i postuppsättningen. Dessa kolumner har redan RFX-instruktioner i din DoFieldExchange funktion.
Kolumner att binda dynamiskt (Lista 3 i bilden) En lista över kolumner i tabellen men inte i postuppsättningen. Det här är de kolumner som du vill binda dynamiskt.
Dynamiska-Kolumnvärden (Lista 4 i bilden) En lista som innehåller lagring för de värden som hämtas från de kolumner som du binder dynamiskt. Elementen i den här listan motsvarar dem i Columns-to-Bind-Dynamically, en mot en.

Skapa dina listor

Med en allmän strategi i åtanke kan du gå till detaljerna. Procedurerna i resten av det här avsnittet visar hur du skapar listorna som visas i Listor med kolumner. Procedurerna vägleder dig genom:

Identifiera vilka tabellkolumner som inte finns i postuppsättningen

Skapa en lista (Bound-Recordset-Columns, som i Lista 2 i bilden) som innehåller en lista över de kolumner som redan är bundna i huvudpostuppsättningen. Sammanställ sedan en lista (Columns-to-Bind-Dynamically, härledd från Current-Table-Columns och Bound-Recordset-Columns) som innehåller kolumnnamn som finns i tabellen på datakällan men inte i din huvudpostuppsättning.

För att fastställa namnen på kolumner som inte finns i postuppsättningen (kolumner tillBind-Dynamically)
  1. Skapa en lista (Bound-Recordset-Columns) för de kolumner som redan är bundna i huvudpostuppsättningen.

    En metod är att skapa Bound-Recordset-Columns vid designtillfället. Du kan enkelt undersöka RFX-funktionsanropen i recordsetets DoFieldExchange-funktion för att få dessa namn. Konfigurera sedan listan som en matris som initierats med namnen.

    Bilden visar till exempel Bound-Recordset-Columns (lista 2) med tre element. Bound-Recordset-Columns saknar kolumnen Telefon som visas i Current-Table-Columns (List 1).

  2. Jämför Current-Table-Columns och Bound-Recordset-Columns för att bygga en lista (kolumner som ska tillBind-Dynamically) över kolumnerna som inte redan är bundna i din huvudpostuppsättning.

    En metod är att gå igenom din lista över kolumner i tabellen under körning (aktuell-Table-Columns) och din lista över kolumner som redan är bundna i postuppsättningen (bundna-Recordset-Columns) parallellt. I Kolumner tillBind-Dynamically placera namn i AktuelltTable-Columns som inte visas i Bound-Recordset-Columns.

    Bilden visar till exempel Kolumner-till-Bind-Dynamically (Lista 3) med ett element: kolumnen Telefon som finns i Current-Table-Columns (Lista 1) men inte i Bound-Recordset-Columns (Lista 2).

  3. Skapa en lista för dynamiskaColumn-Values (som i lista 4 i illustrationen) där du kan lagra de datavärden som motsvarar varje kolumnnamn som lagras i din lista över kolumner som ska bindas dynamiskt (Kolumner-till-Bind-Dynamically).

    Elementen i den här listan fungerar som fältdatainstanser för nya registerfält. De är de lagringsplatser som de dynamiska kolumnerna är bundna till. Beskrivningar av listorna finns i Listor med kolumner.

Tillhandahålla lagring för de nya kolumnerna

Konfigurera sedan lagringsplatser för kolumnerna som ska bindas dynamiskt. Tanken är att tillhandahålla ett listelement där varje kolumns värde ska lagras. Dessa lagringsplatser är parallella med postuppsättningens medlemsvariabler, som lagrar de normalt bundna kolumnerna.

Så här tillhandahåller du dynamisk lagring för nya kolumner (Dynamisk-Column-Values)

  1. Skapa Dynamic-Column-Values parallellt med Columns-to-Bind-Dynamically för att innehålla värdet av data i varje kolumn.

    Bilden visar till exempel Dynamic-Column-Values (Lista 4) med ett element: ett CString objekt som innehåller det faktiska telefonnumret för den aktuella posten: "555-1212".

    I det vanligaste fallet har Dynamic-Column-Values element av typen CString. Om du hanterar kolumner med olika datatyper behöver du en lista som kan innehålla element av olika typer.

Resultatet av föregående procedurer är två huvudlistor: Kolumner-till-Bind-Dynamically som innehåller namnen på kolumnerna och Dynamisk-Column-Values som innehåller värdena i kolumnerna för den aktuella posten.

Tips/Råd

Om de nya kolumnerna inte är av samma datatyp kanske du vill ha en extra parallell lista som innehåller objekt som på något sätt definierar typen av varje motsvarande element i kolumnlistan. (Du kan använda värdena AFX_RFX_BOOL, AFX_RFX_BYTE och så vidare för detta om du vill. Dessa konstanter definieras i AFXDB.H.) Välj en listtyp baserat på hur du representerar kolumndatatyperna.

Lägga till RFX-anrop för att binda kolumnerna

Se slutligen till att den dynamiska bindningen sker genom att placera RFX-anrop för de nya kolumnerna i din DoFieldExchange funktion.

Så här lägger du dynamiskt till RFX-anrop för nya kolumner
  1. I medlemsfunktionen för din huvudpostuppsättning DoFieldExchange lägger du till kod som loopar igenom din lista över nya kolumner (Columns-to-Bind-Dynamically). I varje loop extraherar du ett kolumnnamn från Kolumner tillBind-Dynamically och ett resultatvärde för kolumnen från Dynamic-Column-Values. Skicka dessa objekt till ett RFX-funktionsanrop som är lämpligt för kolumnens datatyp. Beskrivningar av listorna finns i Listor med kolumner.

I det vanliga fallet gör du i dina RFX_Text funktionsanrop att du extraherar CString objekt från listorna, som i följande kodrader, där Columns-to-Bind-Dynamically är en CStringList kallad m_listName och Dynamic-Column-Values är en CStringList kallad m_listValue.

RFX_Text( pFX,
            m_listName.GetNext( posName ),
            m_listValue.GetNext( posValue ));

Mer information om RFX-funktioner finns i Makron och globaler i klassbiblioteksreferensen.

Tips/Råd

Om de nya kolumnerna är olika datatyper använder du en switch-instruktion i loopen för att anropa lämplig RFX-funktion för varje typ.

När ramverket anropar DoFieldExchange under Open-processen för att binda kolumner till postuppsättningen, anropar RFX för att de statiska kolumnerna ska binda dessa kolumner. Sedan anropar loopen rfx-funktioner upprepade gånger för de dynamiska kolumnerna.

Se även

Postuppsättning (ODBC)
Postuppsättning: Arbeta med stora dataobjekt (ODBC)