Вызов хранимой процедуры со строковым выходным параметром

Я хочу вызвать хранимую процедуру в базе данных SQL Server 2022 со строковым выходным параметром, используя API ODBC. Числовые выходные параметры работают нормально, но строковые я не могу заставить работать.

Хранимая процедура:

CREATE PROCEDURE TestStoredProcedure(@inParam VARCHAR(MAX), @outParam VARCHAR(MAX) OUTPUT) AS
BEGIN
  SET @outParam = @inParam;
END;

Фрагмент кода приложения (проверка ошибок опущена):

char* pStr = "{call TestStoredProcedure(?, ?)}";
SQLPrepare(hstmt, pStr, (SQLINTEGER)strlen(pStr));

char inParam[10] = "1234";
char outParam[10] = "";

SQLBindParameter(hstmt,
            (SQLUSMALLINT)1,
            SQL_PARAM_INPUT,
            SQL_C_CHAR,
            SQL_LONGVARCHAR,
            (SQLUINTEGER)strlen(inParam),
            0,
            (SQLPOINTER)inParam,
            sizeof(inParam),
            0);

SQLBindParameter(hstmt,
            (SQLUSMALLINT)2,
            SQL_PARAM_OUTPUT,
            SQL_C_CHAR,
            SQL_LONGVARCHAR,
            (SQLUINTEGER)sizeof(outParam),
            0,
            (SQLPOINTER)outParam,
            sizeof(outParam),
            0);

SQLExecute(hstmt); // error

Ошибка:

[Microsoft][Драйвер ODBC 18 для SQL Server][SQL Server]Недопустимый параметр 4 (''): Данные тип 0x23 — устаревший большой объект или LOB, но помечен как выходной параметр. Устаревшие типы не поддерживаются в качестве выходных параметров. Вместо этого используйте текущие типы больших объектов.

Я пробовал с VARCHAR(5), CHAR(5), NVARCHAR(MAX), но ничего не помогает.

Какими должны быть типы параметров, чтобы это работало, и что такое Invalid parameter 4 ('')?

Использование SQL_SS_LENGTH_UNLIMITED в качестве значения параметра ColumnSize может помочь.

Zhorov 13.09.2023 11:57

В качестве примечания: действительно ли вероятно, что ваши входные и выходные значения будут больше 8000 байт? Если нет, то рассмотрите возможность использования более репрезентативной длины для ваших параметров вместо MAX.

Thom A 13.09.2023 12:14

@ThomA, как указано в вопросе, я пробовал использовать VARCHAR(5) и CHAR(5), но получаю ту же ошибку, что бы я ни делал.

Alex 13.09.2023 12:30

Когда/где вы пробовали varchar(5) и в определении SP, и в привязке одновременно? Тип данных 0x23 — text, это устаревший тип данных.

Thom A 13.09.2023 12:34

@ThomA изменение SQL_LONGVARCHAR на SQL_VARCHAR, похоже, работает для VARCHAR (5).

Alex 13.09.2023 12:53

SQL_VARCHAR работает и для VARCHAR(MAX), поэтому, очевидно, основная проблема заключается в SQL_LONGVARCHAR.

Alex 13.09.2023 13:04

Я не могу найти документацию по нему, но подозреваю, что SQL_LONGVARCHAR соответствует text, поэтому вы и получили ошибку. Я подозреваю, что SQL_WLONGVARCHAR и SQL_LONGVARBINARY также сопоставляются с ntext и image соответственно (которые также устарели).

Thom A 13.09.2023 13:06

Вероятно, эта часть документации актуальна.

Zhorov 13.09.2023 13:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Выходной символ должен быть SQL_VARCHAR, а не SQL_LONGVARCHAR:

SQLBindParameter(hstmt,
            (SQLUSMALLINT)2,
            SQL_PARAM_OUTPUT,
            SQL_C_CHAR,
            SQL_VARCHAR,
            (SQLUINTEGER)sizeof(outParam),
            0,
            (SQLPOINTER)outParam,
            sizeof(outParam),
            0);

Другие вопросы по теме