SQL Server ODBC / T-SQL - передать тип CURSOR вызывающей стороне ODBC? - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть следующий набор шаблонов хранимых процедур T-SQL:

  • Сначала - открыть курсор и передать его обратно вызывающему.
  • Далее - итеративно шагайте по этому курсору и извлекайте данные.
  • Наконец - закройте курсор и освободите его

отлично работает в T-SQL - как показано ниже. - Мне не удается заставить его работать для абонента ODBC.

следующий фрагмент кода завершается ошибкой независимо от типа, переданного в SQLBindParameter(...), показывая следующую ошибку:

res = SQLPrepareW(stmt,(SQLWCHAR *)L"exec CDClog5.dbo.openNationCursor ?", cb);
SQLNumParams(stmt, &NumParams);
res = SQLDescribeParam(stmt,1,&DataType,&bytesRemaining,&DecimalDigits,&Nullable);

res = SQLBindParameter(stmt, 1, SQL_PARAM_OUTPUT, DataType,DataType, 10, 0, &iCursor, 4, &cbParm1);
res = SQLExecDirectW(stmt, (SQLWCHAR *)__EXEC_SP_OPEN__, SQL_NTS);

if( !SQL_OK( res ))
{
    printErrors( SQL_NULL_HENV, SQL_NULL_HDBC, stmt );
    exit( -3 );
}

Ошибка:

SQLState = 22005
Собственная ошибка = 206
Текст сообщения = [Microsoft] [Драйвер ODBC 11 для SQL Server] [SQL Server] Столкновение с типом операнда: int несовместимо с курсором **

Примечание : из-за различных соображений - шаблон хранимой процедуры является ограничением, которое нельзя изменить или обойти.

Пожалуйста, не отвечайте: «Эй, измените его на обычный запрограммированный курсор ODBC». Я бы хотел ...

Что мне здесь не хватало?

Как передать тип CURSOR из / в T-SQL?

Ваша помощь приветствуется.

Спасибо.

Гилель.

/*
    Creation script
    ===============
*/
if object_id('dbo.openNationCursor') is not null
    drop   procedure  dbo.openNationCursor
go
CREATE PROCEDURE dbo.openNationCursor
    @nationCursor CURSOR VARYING OUTPUT
AS
    SET @nationCursor = CURSOR
    FORWARD_ONLY STATIC FOR
      SELECT n_nationkey,n_name
      FROM dbo.nation order by 1
    OPEN @nationCursor;
-- ===========================

if object_id('dbo.closeNationCursor') is not null
    drop PROCEDURE dbo.closeNationCursor
go
CREATE PROCEDURE dbo.closeNationCursor
    @nationCursor CURSOR VARYING output
AS
    close @nationCursor;
    DEALLOCATE @nationCursor; 
GO
-- ===========================

if object_id('dbo.fetchNationCursor') is not null
    drop PROCEDURE dbo.fetchNationCursor
go
CREATE PROCEDURE dbo.fetchNationCursor
    @nationCursor CURSOR VARYING output,
    @n_nationkey  integer output,
    @n_name       varchar(64) output
AS
    FETCH NEXT FROM @nationCursor INTO @n_nationkey,@n_name 
GO

-- ===========================
-- Execute from TSQL
-- ===========================

DECLARE @MyCursor CURSOR; 
declare @n_nationkey integer
declare @n_name varchar(64)

EXEC dbo.openNationCursor @nationCursor  = @MyCursor OUTPUT;  

EXEC dbo.fetchNationCursor @nationCursor  = @MyCursor, @n_nationkey  = @n_nationkey output, @n_name = @n_name output

WHILE (@@FETCH_STATUS = 0)  
BEGIN 
     print cast(@n_nationkey as varchar(10))+' '+@n_name
    EXEC dbo.fetchNationCursor @nationCursor  = @MyCursor, @n_nationkey  = @n_nationkey output, @n_name = @n_name output
END 
EXEC dbo.closeNationCursor @nationCursor  = @MyCursor;   
GO  

0 АЛЖИР
1 АРГЕНТИНА
2 БРАЗИЛИЯ
3 КАНАДА
4 ЕГИПЕТ
5 ЭФИОПИЯ
6 ФРАНЦИЯ
7 ГЕРМАНИЯ

Итак - процедуры работают нормально при вызове из TSQL, но не выполняются на самом базовом этапе инициализации при вызове из ODBC Любая подсказка?

...