Udostępnij za pośrednictwem


Wysyłanie danych jako parametr oródwierszową ze wszystkimi wartościami w pamięci (ODBC)

W tym temacie opisano sposób wysyłać dane do procedura składowana jako tabela-parametr wyceniane, gdy wszystkie wartości w pamięci.

Wymagania wstępne

W tej procedurze założono, że następujące Transact-SQL zostało uruchomione na serwerze:

create type TVParam as table(ProdCode integer, Qty integer)
create procedure TVPOrderEntry(@CustCode varchar(5), @Items TVPParam, 
            @OrdNo integer output, @OrdDate datetime output)
         as 
         set @OrdDate = GETDATE();
         insert into TVPOrd (OrdDate, CustCode) 
values (@OrdDate, @CustCode) output OrdNo); 
         select @OrdNo = SCOPE_IDENTITY(); 
         insert into TVPItem (OrdNo, ProdCode, Qty)
select @OrdNo, @Items.ProdCode, @Items.Qty 
from @Items

Aby wysłać dane

  1. Deklaruje zmienne dla parametrów SQL.W tym przypadek wartość tabela jest przechowywana całkowicie w pamięci, więc wartości dla kolumn tabela wartości są zgłoszone jako tablice.

    SQLRETURN r;
    // Variables for SQL parameters.
    #define ITEM_ARRAY_SIZE 20
    
    SQLCHAR CustCode[6];
    SQLCHAR *TVP = (SQLCHAR *) "TVParam";
    SQLINTEGER ProdCode[ITEM_ARRAY_SIZE], Qty[ITEM_ARRAY_SIZE];
    SQLINTEGER OrdNo;
    char OrdDate[23];
    
    // Variables for indicator/length variables associated with parameters.
    SQLLEN cbCustCode, cbTVP, cbProdCode[ITEM_ARRAY_SIZE], cbQty[ITEM_ARRAY_SIZE], cbOrdNo, cbOrdDate;
    
  2. Powiązania parametry.Parametry wiążące się dwóch etap procesu, kiedy tabela-parametry wyceniane są używane.W pierwszym etapie kroku parametry procedura składowana są powiązane w normalny sposób, w następujący sposób.

    // Bind parameters for call to TVPOrderEntryDirect.
    // 1 - Custcode input
    r = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,SQL_VARCHAR, SQL_C_CHAR, 5, 0, CustCode, sizeof(CustCode), &cbCustCode);
    
    // 2 - Items TVP
    r = SQLBindParameter(hstmt, 
        2,// ParameterNumber
        SQL_PARAM_INPUT,// InputOutputType
        SQL_C_DEFAULT,// ValueType 
        SQL_SS_TABLE,// Parametertype
        ITEM_ARRAY_SIZE,// ColumnSize: For a table-valued parameter this is the row array size.
        0,// DecimalDigits: For a table-valued parameter this is always 0. 
        TVP,// ParameterValuePtr: For a table-valued parameter this is the type name of the 
    //table-valued parameter, and also a token returned by SQLParamData.
        SQL_NTS,// BufferLength: For a table-valued parameter this is the length of the type name or SQL_NTS.
        &cbTVP);// StrLen_or_IndPtr: For a table-valued parameter this is the number of rows actually used.
    
    // 3 - OrdNo output
    r = SQLBindParameter(hstmt, 3, SQL_PARAM_OUTPUT,SQL_INTEGER, SQL_C_LONG, 0, 0, &OrdNo,
       sizeof(SQLINTEGER), &cbOrdNo);
    // 4 - OrdDate output
    r = SQLBindParameter(hstmt, 4, SQL_PARAM_OUTPUT,SQL_TYPE_TIMESTAMP, SQL_C_CHAR, 23, 3, &OrdDate, 
       sizeof(OrdDate), &cbOrdDate);
    
  3. Drugi etap wiązania parametr jest powiązać kolumn dla tabela-parametr wycenione.Parametr fokus ustawiono wcześniej liczba porządkowa tabela-parametr wycenione.Następnie kolumn wartość tabela są powiązane przy użyciu SQLBindParameter w taki sam sposób jak byłyby, gdyby parametry procedura składowana, ale liczby porządkowe kolumna dla ParameterNumber.W przypadku braku więcej tabela-wyceniane parametry możemy ustawić fokus na każdej z kolei i powiązania ich kolumnach.Wreszcie fokus parametr jest zerowany.

    // Bind columns for the table-valued parameter (param 2).
    // First set focus on param 2.
    r = SQLSetStmtAttr(hstmt, SQL_SOPT_SS_PARAM_FOCUS, (SQLPOINTER) 2, SQL_IS_INTEGER);
    
    // Col 1 - ProdCode
    r = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,SQL_INTEGER, SQL_C_LONG, 0, 0, ProdCode, sizeof(SQLINTEGER), cbProdCode);
    // Col 2 - Qty
    r = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT,SQL_INTEGER, SQL_C_LONG, 0, 0, Qty, sizeof(SQLINTEGER), cbQty);
    
    // Reset param focus.
    r = SQLSetStmtAttr(hstmt, SQL_SOPT_SS_PARAM_FOCUS, (SQLPOINTER) 0, SQL_IS_INTEGER);
    
  4. Populate the parameter buffers.cbTVP is set to the number of rows to be sent to the server.

    // Populate parameters.
    cbTVP = 0; // Number of rows available for input.
    strcpy_s((char *) CustCode, sizeof(CustCode), "CUST1"); cbCustCode = SQL_NTS;
    
    ProdCode[cbTVP] = 1215;cbProdCode[cbTVP] = sizeof(SQLINTEGER); 
    Qty[cbTVP] = 5;cbQty[cbTVP] = sizeof(SQLINTEGER); 
    cbTVP++; // Number of rows available for input
    
    ProdCode[cbTVP] = 1017;cbProdCode[cbTVP] = sizeof(SQLINTEGER); 
    Qty[cbTVP] = 2;cbQty[cbTVP] = sizeof(SQLINTEGER); 
    cbTVP++; // Number of rows available for input.
    
  5. Wywołanie procedury:

    // Call the procedure.
    r = SQLExecDirect(hstmt, (SQLCHAR *) "{call TVPOrderEntry(?, ?, ?, ?)}",SQL_NTS);