powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Ф-я возвращает setof record. Как обработать на C#?
15 сообщений из 15, страница 1 из 1
Ф-я возвращает setof record. Как обработать на C#?
    #34280402
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго всем времени суток!
С postgreSql совсем недавно и наступаю на очередные грабли...

Есть функция

Код: plaintext
1.
2.
3.
4.
CREATE FUNCTION admin_getroles() RETURNS SETOF record AS
$BODY$
select oid, rolname as roles from pg_roles where rolcanlogin = false;
$BODY$
LANGUAGE 'sql' STABLE;

Клиент .NET WinForms. На C#.
Код такой:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
using (Npgsql.NpgsqlConnection conn = new Npgsql.NpgsqlConnection(_full_connectionString))
{
    conn.Open();
    using (Npgsql.NpgsqlCommand cmd = new Npgsql.NpgsqlCommand("admin_getroles", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        using (Npgsql.NpgsqlDataReader rd = cmd.ExecuteReader())
        {
            while (rd.Read())                     // ***
            {
                 // Как и что тут обработать?
            }
        }
    }
}
При вызове cmd.ExecuteReader() вываливается исключение с текстом "ERROR: 42601: a column definition list is required for functions returning \"record\"". Подскажите, как выпрямить код? Пробовал шаманить и с параметрами, но без толку...
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34280661
Serik Akhmetov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какой запрос посылает клиент ?
Если
Код: plaintext
select  * from admin_getroles()
и вы не можете его обработать, то это вопрос в конференцию по ЯП.
Думаю дело в
Код: plaintext
CommandType.StoredProcedure;
Попробуйте явно написать запрос.
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34280784
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Явно написать запрос - это, конечно, можно. Точно так же, как и писать функции, которые возвращают только какие-то одни данные (например, setof oid или setof name , Только для запросов придется делать NpgsqlCommand.Prepare() , и все равно такой подход мне не нравится, т.к. сервер для каждого запроса каждый раз будет вычислять план, что скажется на производительности. Ну не подходит мне это. Да и не верю, что нужная мне функциональность не реализована в постгрессе, "это же азы" (с) не помню, как говорится.
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34280848
Serik Akhmetov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже мы говорим о разном. Я подозреваю что приложение посылает запрос
Код: plaintext
 ( 1 ) select admin_getroles()
а это совсем не то же, что
Код: plaintext
 ( 2 ) select * from admin_getroles()
и я вам предлагаю в первую очередь выяснить это. Если же все таки запрос (2), то мне не понятно, чем обработка результата на клиенте отличается от
Код: plaintext
select * from pg_roles
т.е. результат выборки из таблицы и из функции обрабатывается одинаково.

Для каждого вашего запроса сервер в любом случае будет вычислять план. План выполнения процедуры хранится, насколько это хорошо - вопрос спорный.
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34281452
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Включил лог у провайдера данных и все выяснилось. Весь лог не выкладываю, в двух-фразах: провайдер данных после нескольких итераций обмена инфой с сервером выдает ему запрос select * from admin_getroles() . :(
После правки кода следующим образом
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
using (Npgsql.NpgsqlCommand cmd = new Npgsql.NpgsqlCommand("select admin_getroles()", conn))
{
   cmd.CommandType = CommandType.Text;                  
   using (Npgsql.NpgsqlDataReader rd = cmd.ExecuteReader())
   {
      while (rd.Read())
      {
      }
   }
}
Все заработало, но не понравилось, и сильно, то, что сервер все данные (столбцы) валит в одну строку типа "17090,administrators". Парсить ее желания как-то нет, да и на производительности скажется. Не подскажете другого способа, окромя returns setof record или создания своих типов, возвращать из функций многострочные данные в нескольких колонках?
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34281506
BeerSeller
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробуйте запрос вида:
Код: plaintext
select t.* from admin_getroles()t (oid oid,name text)
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34281583
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо большое, это решение работает. Но в свете предыдущего бага буду теперь крепко думать, делать ли проект на PostgreSql, или же как и планировал изначально, сделать все на Firebird'е, хотя и у него не без глюков :(
Но все же интересно, можно ли из функции вернуть данные так же, как и из такого запроса, что приведен выше.
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34281788
BeerSeller
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гляньте сюда:

тынц
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34281955
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Глянул. В который раз. И похоже, что дорога одна - к созданию типов или же делать запросы наподобие вышеприведенного. Буду теперь думать, как лучше сделать.
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34282236
st_serg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а вам обязательно использовать set of функции? может проще было бы возвращать курсор приложению?
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34282867
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Оно-то можно, но как-то некрасиво получается :)
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34283196
СергейК
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Yuriy YurchenkoСпасибо большое, это решение работает. Но в свете предыдущего бага буду теперь крепко думать, делать ли проект на PostgreSql, или же как и планировал изначально, сделать все на Firebird'е, хотя и у него не без глюков :(
Но все же интересно, можно ли из функции вернуть данные так же, как и из такого запроса, что приведен выше.

Pardon ,a chto meshaet vam opredelit' f-iu s OUT parametrami:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE FUNCTION admin_getroles(OUT oidd  oid, OUT rolname text) RETURNS SETOF record AS
$BODY$
select oid, rolname as roles from pg_roles where rolcanlogin = false;
$BODY$
LANGUAGE 'sql' STABLE;
[src]

I vse budet rabotat' v 
zaprose:
[src]SELECT * from admin_roles();
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34283349
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
СергейК
А что, в постгрессе через out-параметры можно получить данные из нескольких строк?
Например,
Код: plaintext
1.
2.
 17090  admins
 17091  users
 17092  managers
и т.д.

В документации я это что-то не встречал, да и синтаксис SQL как языка не позволяет... :D
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34283361
СергейК
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Yuriy Yurchenko
В документации я это что-то не встречал, да и синтаксис SQL как языка не позволяет... :D

:-))
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
wsdb=# CREATE  FUNCTION  xxx (out ra double precision, out decl double precision ) returns  setof record as 'select ra,dec from q3c limit 10' language sql;
CREATE FUNCTION
wsdb=# select * from xxx();
        ra        |       decl       
------------------+------------------
  315 . 053863525391  |  35 . 4002532958984 
  315 . 251159667969  |  35 . 4605941772461 
  315 . 426116943359  |  35 . 4647598266602 
  315 . 367126464844  |  35 . 4711647033691 
  315 . 313140869141  |  35 . 4901657104492 
  315 . 088409423828  |   35 . 511344909668 
  314 . 847381591797  |  35 . 4387741088867 
   314 . 89892578125  |  35 . 4570846557617 
  314 . 743591308594  |   35 . 461856842041 
  314 . 754913330078  |  35 . 5428085327148 
( 10  rows)
...
Рейтинг: 0 / 0
Ф-я возвращает setof record. Как обработать на C#?
    #34283506
Yuriy Yurchenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мда.. это работает. 8-D Теперь уже даже и не знаю, что думать.. :)
Но наверное все же выберу вариант с пользовательскими типами. Как-то привычнее получается. :)
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Ф-я возвращает setof record. Как обработать на C#?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]