Попытка привязать строковый столбец для табличного параметра с использованием ODBCC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Попытка привязать строковый столбец для табличного параметра с использованием ODBC

Сообщение Anonymous »

Как сказано в заголовке, я пытаюсь привязать строковый столбец для таблицы, оцененный параметр с использованием ODBC. < /p>
До сих пор я создал таблицу, подобная этому: < /p>

Код: Выделить всё

CREATE TABLE [dbo].[TVPItem]
(
ItemNo      INT IDENTITY(1,1) NOT NULL,
ProdCode    VARCHAR(100),
Qty         INT
)
< /code>
и TVPCREATE TYPE [dbo].[TVPParam]
AS TABLE
(
ProdCode    VARCHAR(100),
Qty         INT
)
< /code>
и процедура, которая принимает TVP для вставки в таблицу: < /p>
CREATE PROCEDURE [dbo].[TVPOrderEntry]
(
@Items      dbo.TVPParam READONLY
)
AS
BEGIN
INSERT INTO dbo.TVPItem (ProdCode, Qty)
SELECT ProdCode, Qty
FROM @Items;
END;
< /code>
и проект Vs2022 C ++, содержащий < /p>
#include 
#include 
#include 
#include 
#include "sql.h"
#include "sqlext.h"
#include "msodbcsql.h"

#include 
#include 
#include 

// cardinality of order item related array variables
#define ITEM_ARRAY_SIZE 4

// struct to pass order entry data
typedef struct OrdEntry_struct
{
SQLUINTEGER ItemCount;
std::array ProdCode;
std::array Qty;
} OrdEntryData;

SQLHANDLE henv, hdbc, hstmt;
TCHAR szConnStrIn[256] = _T("DSN=SampleDSN;UID=test;PWD=test");

static void connect()
{
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);

// This is an ODBC v3 application
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);

SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

// Run in ANSI/implicit transaction mode
SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);

SQLDriverConnect(hdbc, NULL, (SQLTCHAR*)szConnStrIn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
}

static void OrdEntry_TVP(OrdEntryData& order)
{
// Initialize TVP row count
// Variable for TVP row count
SQLLEN cbTVP = order.ItemCount;

// Bind parameters for call to TVPOrderEntry
// 1 - Items TVP
SQLBindParameter(
hstmt,
1,// ParameterNumber
SQL_PARAM_INPUT,// InputOutputType
SQL_C_DEFAULT,// ValueType
SQL_SS_TABLE,// Parametertype
ITEM_ARRAY_SIZE,// ColumnSize - for a TVP this the row array size
0,// DecimalDigits - DecimalDigits: For a table-valued parameter this must always be 0.
NULL,// ParameterValuePtr - for a TVP this is the type name of the TVP
// (not needed with stored proc)
NULL,// BufferLength - for a TVP this is the length of the type name or SQL_NTS
// (not needed with stored proc)
&cbTVP);// StrLen_or_IndPtr - for a TVP this is the number of rows available

// Bind columns for the TVP
// First set focus on param
SQLSetStmtAttr(hstmt, SQL_SOPT_SS_PARAM_FOCUS, (SQLPOINTER)1, SQL_IS_INTEGER);

std::vector strings;
strings.reserve(order.ItemCount);

std::vector stringsLength;
stringsLength.reserve(order.ItemCount);

for (int i = 0; i < order.ItemCount; i++)
{
strings.push_back(const_cast(order.ProdCode[i].c_str()));
stringsLength.push_back(order.ProdCode[i].size());
}

// Col 1 - ProdCode
SQLBindParameter(
hstmt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_VARCHAR,
0, 0, strings[0],
sizeof(char*), &stringsLength[0]);

// Col 2 - Qty
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, order.Qty.data(), sizeof(SQLINTEGER), NULL);

// Reset param focus
SQLSetStmtAttr(hstmt, SQL_SOPT_SS_PARAM_FOCUS, (SQLPOINTER)0, SQL_IS_INTEGER);

// Call one procedure which inserts both the order and items
SQLExecDirect(hstmt, (SQLTCHAR*)_T("{call TVPOrderEntry(?)}"), SQL_NTS);

// Flush results &  reset hstmt
SQLMoreResults(hstmt);

SQLFreeStmt(hstmt, SQL_RESET_PARAMS);

// Commit the transaction
SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
}

int main()
{
connect();
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);

OrdEntryData order;

order.ProdCode[0] = "1000";
order.Qty[0] = 100;
order.ProdCode[1] = "2000";
order.Qty[1] = 200;
order.ProdCode[2] = "3000";
order.Qty[2] = 300;
order.ProdCode[3] = "4000";
order.Qty[3] = 400;
order.ItemCount = 4;

OrdEntry_TVP(order);
}
Я настроил пользователь DSN с именем SampledSn, который указывает на мой локальный тест db.
Вот что содержит таблица после завершения выполнения кода:


Подробнее здесь: https://stackoverflow.com/questions/796 ... using-odbc
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»