Как вызвать пользовательскую функцию из c с помощью ADO

#c #sql-server-2008 #ado

#c #sql-server-2008 #ado

Вопрос:

Я пытаюсь вызвать пользовательскую функцию на моем сервере Microsoft SQL Server из консольного приложения, написанного на c . Я использую ADO для всего этого.

Моя функция выглядит следующим образом (и она работает, когда я использую ее из management studio)

 CREATE FUNCTION [dbo].[funcHowOftenDidHeWin] 
(
    @playername as varchar(15)
    @percentWon float OUTPUT
)
RETURNS float
AS
BEGIN
    DECLARE @wintimes float
    DECLARE @participated float
    DECLARE @percentWon float

    SELECT @wintimes = COUNT(DidWin)
    FROM PPLP0p02
    WHERE DidWin = 1 AND Playername=@playername

    SELECT @participated = COUNT(DidWin)
    FROM PPLP0p02
    WHERE Playername = @playername

    IF @wintimes >0
        SET @percentWon = @wintimes  / @participated  *100
    IF @wintimes = 0
        SET @percentWon = 0

    RETURN @percentWon
END
GO
  

Из моей программы я пытаюсь вызвать ее следующим образом:

 USEADO::_ConnectionPtr connection;                              
USEADO::_RecordsetPtr recordset;                                //create a "

    if(FAILED(hr = CoInitialize(NULL)))                         //
    {   return hr;} 

   if(FAILED(hr = connection.CreateInstance(__uuidof(USEADO::Connection))))
    {  return hr;}

   if(FAILED(hr = recordset.CreateInstance(__uuidof(USEADO::Recordset))))
    {   return hr;}

connection->CursorLocation = USEADO::adUseServer; 


    try
   { 
    connection->Open(L"Provider=SQLOLEDB.1;Persist Security Info=False;User ID=Test;Initial  Catalog=Haufen;Data Source=Wolle\SQLEXPRESS", L"Test", L"Test", USEADO::adConnectUnspecified);    
   }
    catch(...)  {std::cout << "!!! connection->Open(ConnectionString   FAILED !!!" << std::endl;        }



//This works
recordset->Open("SELECT playername FROM Summary WHERE playersatbegin=5",connection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);


//This not
recordset->Open("SELECT dbo.funcHowOftenDidHeWin('Lumpi') ",connection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
  

Ну, это не работает. Отладчик завершается на masado15.tli в строке 1580, и VS показывает окно с ошибкой: необработанное исключение в 0x7c812afb в 35h.exe : Исключение Microsoft C : _com_error в ячейке памяти 0x0012c3f8.

Я не уверен, что синтаксис правильный, интересно, как сервер должен знать, из какой таблицы я хочу получить результаты….

Есть какая-нибудь помощь? Спасибо

Lumpi

Комментарии:

1. Вы получаете сообщение об ошибке? Если да … вставьте это сюда.

2. Ошибка: Необработанное исключение в 0x7c812afb в 35h.exe : Исключение Microsoft C : _com_error в ячейке памяти 0x0012c3f8..

Ответ №1:

Вы можете переписать функцию как хранимую процедуру. Значение FLOAT может быть возвращено либо как ВОЗВРАЩАЕМОЕ значение, либо как параметр OUT.

Комментарии:

1. Я пробовал это с помощью хранимой процедуры, тоже не работает. Я думаю, что проблема в чем-то другом. например, правильно ли использовать recordset-> открыть? Должен ли я что-то сделать (инициализировать), прежде чем попробовать это??

2. Я знаю, что она должна работать с хранимой процедурой, если текущему пользователю предоставлено разрешение на выполнение в proc. Вы можете либо переписать как SP, либо обернуть функцию в SP. Опубликуйте свой код, в котором вы пытаетесь вызвать сохраненную процедуру, вместе с любыми ошибками.

3. Ваша функция не возвращает набор записей. Она возвращает скаляр.

4. Я подумал, что это может быть что-то вроде этого .. Ок, общий вопрос newbee: Какие данные вместо набора записей я должен использовать? Я переписал ее как sp, не работает, я проверю разрешения. Спасибо