Проблема в использование хранимой процедуры

    Код процедуры:

CREATE OR REPLACE FUNCTION __add_game(IN player integer, IN comm text, IN move1 integer, OUT id_game1 integer)
RETURNS integer AS
$BODY$begin
INSERT INTO game (state,player1,comment,date_begin,fmove) VALUES ('ожидает',player,comm,now(),move1);
id_game1:= currval('game_id_game_seq');

end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
ALTER FUNCTION __add_game(integer, text, integer) OWNER TO postgres;

подсоединяюсь таким образом:

OdbcConnection con=new OdbcConnection(_conString);
OdbcCommand cmd = new OdbcCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "ADD_GAME";
cmd.Parameters.Add("player", OdbcType.Int);
cmd.Parameters.Add("comm", OdbcType.Char);
cmd.Parameters.Add("move1", OdbcType.Int);
cmd.Parameters.Add("id_game1", OdbcType.Int);
cmd.Parameters["player"].Value = pl;
cmd.Parameters["comm"].Value = com;
cmd.Parameters["move1"].Value = Move;
cmd.Parameters["id_game1"].Direction = ParameterDirection.Output;
try
{
con.Open();
cmd.ExecuteNonQuery();
con.Close();
return Convert.ToInt32(cmd.Parameters.Add("id_game1"));
}
catch(Exception ex)
{ return -1; }
finally
{
if (con.State == ConnectionState.Open) con.Close();
cmd.Dispose();
}

---------------------------
во время выполнения ExecuteNonQuery() выскакивает такой эксепшен :

ERROR [42601] ERROR: syntax error at or near "__add_game";
Error while executing the query

думал что проблема в возращаемом параметре, но когда переделал процедуру и вызов её из клиента(просто убрад возвращаемый параметр), то всеравно осталась данная проблема.
хотя как нистранно
подключение вот такое срабатывает без проблем(но только таким макаром не знаю как поймать возвращаемой значение профедуры.
int pl=1;
string com ="блаблабла";
int move1=2358;
string QueryString="SELECT * FROM__add_game (" + pl + ",\'" + com + "\',"+move1+")";
OdbcConnection con=new OdbcConnection(_conString);
OdbcCommand Command = new OdbcCommand(QueryString, con);
con.Open();
Command.ExecuteReader();
con.Close();
return true;

ктонить объясните в чем дело. так как возвращать параметры мне жизнено необходимо

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Нашел способ

Нашел способ добывать данные выходные с помощью второго способа.
Но всеже остается загадкой почему первый способ вызова хранимых процедур не работает, когда именно он является дефолтным способом который описан много где?

точно?

Прям так много где и описан: id_game1:= currval('game_id_game_seq'); ?
Думаю, что как минимум: SELECT INTO id_game1 currval( ...
Да и к тому же не видно, чтоб Вы до этого вызывали nextval, а без этого currval не работает.

непонятно

pwlad,
id_game1:= CURRVAL(...
и
SELECT INTO id_game1 CURRVAL(...
это одно и то же, все нормально.

по поводу вопроса немного не понял
что такое "ADD_GAME"?
почему в ошибке фигурирует "__add_game", если в параметрах такой строки нет? или вы чего-то недоговариваете

я б лучше не заморачивался с процедурами, а сделал через селект

SELECT __add_game(....

"ADD_GAME" - это я

"ADD_GAME" - это я описался просто много раз переписывал процедуру и нечайной не поменял когда копировал. ПОповоду того что nexval нужно вызвать, он вызывается когда инсерт делаетс так как на ид поле стоит сиквенс. А поповоду того что селектом делать - именно этот способ и выбрал, он мне показался кстате намного проще и более унивирсальнее

кстати вашу

кстати вашу процедуру можно переписать в SQL так:

CREATE OR REPLACE FUNCTION __add_game(IN player integer, IN comm text, IN move1 integer, 
   OUT id_game1 integer)
RETURNS integer AS
$BODY$begin
INSERT INTO game (state,player1,comment,date_begin,fmove) VALUES ('ожидает',player,comm,now(),move1);
SELECT currval('game_id_game_seq');
end;
$BODY$
LANGUAGE 'sql' 

а в plpgsql в одну строку (при условии, что на id стоит default-значение nextval('game_id_game_seq'))

CREATE OR REPLACE FUNCTION __add_game(IN player integer, IN comm text, IN move1 integer, 
   OUT id_game1 integer)
RETURNS integer AS
$BODY$begin
INSERT INTO game (state,player1,comment,date_begin,fmove) VALUES ('ожидает',player,comm,now(),move1) 
   returning id_game INTO id_game1;
end;
$BODY$
LANGUAGE 'plpgsql' 

реально работает?

Сорри, если где-то кого-то ввел в заблуждение.
По-поводу последних 2-х примеров - действительно будет работать?
Из документации про CURRVAL этого не следует (или я плохо читал).
Насчет второго примера иду курить маны INSERT применительно postgresql.

да, первый

да, первый пример не будет работать, только щас заметил - переборщил с копипастом :)
Но, если переписать:

CREATE OR REPLACE FUNCTION __add_game(IN player INTEGER, IN comm text, IN move1 INTEGER)
RETURNS INTEGER AS
$BODY$begin
INSERT INTO game (state,player1,COMMENT,date_begin,fmove) VALUES ('ожидает',$1,$2,now(),$3);
SELECT CURRVAL('game_id_game_seq');
END;
$BODY$
LANGUAGE 'sql' 

все должно быть нормально.
С CURRVAL как раз ничего удивительного не вижу... а что увидели вы?...
разьве что можно записать так currval('game_id_game_seq'::regclass), но работает и без явного приведения типов

currval

Вот что в руководстве.
Return value most recently obtained with nextval for specified sequence.
я так понял, что нужно явно вызвать nextval, чтоб currval сработало (а то, что default значение поля вызывает nextval, то это на уровне ограничений таблицы).
Видать ошибся. Действительно РАБОТАЕТ (правда begin end нужно убрать из примера. LANGUAGE 'sql' всё-таки).
Насчет INSERT RETURNING опять же браво postgresql ! Насколько я знаю в Oracle в версии 10g такая конструкция появилась.
Спасибо форуму и людям в нём, а то б так и работал по-старинке.

да все

да все правильно в руководстве написано. Хотя как-то это странновато.

SELECT currval('test_cs_id_seq');
--ERROR:  currval of sequence "test_cs_id_seq" is not yet defined in this session
 
SELECT NEXTVAL('test_cs_id_seq');
--10003
 
SELECT currval('test_cs_id_seq');
--10003

пока в текущей сессии не вызовешь nextval, currval не работает
но можно выкрутиться так

SELECT last_value FROM "test_cs_id_seq";

к автору

а почему вы не используете родные библиотеки libpq?

Как я понял libpq

Как я понял libpq библиотека для C.
Клиент для бд пишется на C#

и туда даже

и туда даже заголовочный файл нельзя прицепить? странно, все-таки С, хоть и за решеткой

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023