Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
1305 / 359 / 97
Регистрация: 14.10.2022
Сообщений: 1,090

Можно ли объявить переменные для запроса?

27.04.2024, 11:06. Показов 790. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Коллеги, приветствую!

Перетаскиваем приложение с MS SQL на PostgreSQL.
Приложение - двухзвенка, запросы формируются в клиентской части, фактически, это литералы в коде программы, которые отдаются MS SQL примерно так:
T-SQL
1
2
3
4
5
6
7
8
9
DECLARE @regionId int ; 
DECLARE @servicepointId varchar(4); 
DECLARE @workstationId varchar(7); 
begin
    Set @regionId = 34; 
    Set @servicepointId = '3401'; 
    Set @workstationId = '340101'; 
    SELECT value FROM erz_system_config WHERE description = '333' AND region_id = @regionId AND (@servicepointId is null OR servicepoint_id = @servicepointId) AND (@workstationId is null OR workstation_id = @workstationId);
end
Set в примере, в целом, для наглядности, т.к. в основном, такие конструкции препарируются как параметризованные запросы, а потом параметр заполняется через объект parameter sqlcommand-a.
Но и вышеописанный вариант, когда переменные объявлены в тексте, и в тексте же и присвоены - тоже встречаются постоянно ("Таков путь", и не нами заведено).

Вопрос: Можно ли это портировать на постгресс, с минимальными переделками?
Например:
Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
DO language plpgsql
$$
DECLARE regionId int ; 
DECLARE servicepointId VARCHAR(4); 
DECLARE workstationId VARCHAR(7); 
BEGIN
    regionId := 34; 
    servicepointId := '3401'; 
    workstationId := '340101'; 
    SELECT VALUE FROM erz_system_config WHERE description = '333' AND region_id = regionId AND (servicepointId IS NULL OR servicepoint_id = servicepointId) AND (workstationId IS NULL OR workstation_id = workstationId);
END
$$;
и на селекте падает с ошибкой
ERROR: query has no destination for result data

Или так:
Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
DO language plpgsql
$$
DECLARE regionId int ; 
DECLARE servicepointId VARCHAR(4); 
DECLARE workstationId VARCHAR(7); 
DECLARE tmp text;
BEGIN
    regionId := 34; 
    servicepointId := '3401'; 
    workstationId := '340101'; 
    SELECT VALUE INTO tmp FROM erz_system_config WHERE description = '333' AND region_id = regionId AND (servicepointId IS NULL OR servicepoint_id = servicepointId) AND (workstationId IS NULL OR workstation_id = workstationId);
    RETURN tmp;
END
$$;
ERROR: RETURN cannot have a parameter in function returning void
LINE 12: return tmp;

Помогите, плз? Куды бечь то?

Добавлено через 4 минуты
Вот такой вариант, ИМХО, нечто вообще запредельное:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
DO LANGUAGE plpgsql
$$
DECLARE regionId INT ; 
DECLARE servicepointId VARCHAR(4); 
DECLARE workstationId VARCHAR(7); 
DECLARE tmp text;
BEGIN
    regionId := 34; 
    servicepointId := '3401'; 
    workstationId := '340101'; 
    CREATE TEMPORARY TABLE t ON commit DROP AS SELECT VALUE FROM erz_system_config WHERE region_id = regionId AND (servicepointId IS NULL OR servicepoint_id = servicepointId) AND (workstationId IS NULL OR workstation_id = workstationId);
END
$$;
SELECT * FROM t;
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
27.04.2024, 11:06
Ответы с готовыми решениями:

Можно ли объявить однотипные переменные, указав тип лишь раз
Часто приходится объявлять несколько переменных одного типа. Например Dim K As Integer, L As Integer... Хотелось бы сократить запись...

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

Объявить переменные для группы процедур
Вот процедура открытия проекта procedure TForm1.MenuItem3Click(Sender: TObject);//открыть проект //карта // var stroka:string; ...

8
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
27.04.2024, 11:35
cte использовать. не?
SQL
1
2
3
WITH cte(n) AS
  (SELECT 1)
SELECT * FROM mytable m JOIN cte ON m.id=cte.n
add
в psql \set
0
1305 / 359 / 97
Регистрация: 14.10.2022
Сообщений: 1,090
27.04.2024, 12:02  [ТС]
Цитата Сообщение от Аватар Посмотреть сообщение
cte использовать. не?
А параметризовать то это как? Ну, извне чтобы подкидывать значение переменных.
0
139 / 105 / 36
Регистрация: 27.07.2022
Сообщений: 357
27.04.2024, 12:33
Через prepared statement?
0
1305 / 359 / 97
Регистрация: 14.10.2022
Сообщений: 1,090
27.04.2024, 12:53  [ТС]
Ну да. В итоге то как это должно выглядеть, покажите, пожалуйста!
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
27.04.2024, 13:31
если такое прокатит в параметризованном запросе
SQL
1
(SELECT :param1)
Добавлено через 15 минут
в общем то и без cte можно этот параметр точно так же засунуть
0
670 / 293 / 120
Регистрация: 12.04.2022
Сообщений: 1,002
27.04.2024, 14:01
Цитата Сообщение от uaggster Посмотреть сообщение
Вопрос: Можно ли это портировать на постгресс, с минимальными переделками?
Обычно обходят эти грабли через CREATE TEMPORARY (pg_temp) FUNCTION.
0
106 / 67 / 29
Регистрация: 22.04.2022
Сообщений: 232
28.04.2024, 07:44
Можно сделать так...
SQL
1
2
3
4
5
6
7
8
9
PREPARE q(INTEGER,VARCHAR(4),VARCHAR(7)) AS
SELECT VALUE FROM erz_system_config 
WHERE 
      description = '333' 
      AND region_id = $1 
      AND (servicepoint_id IS NULL OR servicepoint_id = $2) 
      AND (workstation_id  IS NULL OR workstation_id = $3)
;
EXECUTE q(1,'222','77777');
0
912 / 286 / 57
Регистрация: 01.06.2023
Сообщений: 811
28.04.2024, 12:08
uaggster, основная проблема в том что do явно не может возвращать данные, но она может влиять косвенно. С входными параметрами допустим разобрались, вы их вставляет как литералы. выходные параметры можно передать через открытый курсор. Да, это потребует изменение логики работы приложения.

т.е работа будет выглядеть примерно так

Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DO language plpgsql
$$
DECLARE regionId int ; 
DECLARE servicepointId VARCHAR(4); 
DECLARE workstationId VARCHAR(7); 
DECLARE cur refcursor := 'transitcursor1';
BEGIN
    regionId := 34; 
    servicepointId := '3401'; 
    workstationId := '340101'; 
    OPEN cur FOR SELECT VALUE FROM erz_system_config WHERE description = '333' AND region_id = regionId AND (servicepointId IS NULL OR servicepoint_id = servicepointId) AND (workstationId IS NULL OR workstation_id = workstationId);
END;
 
FETCH ALL FROM  transitcursor1;
$$;
не забываем после того как прочитали все данные закрыть курсор

Oracle 11 SQL
1
CLOSE transitcursor1;
Если до окончания чтения курсора необходимо получить еще данные с сервера, то нужно использовать другое имя курсора, мы например используем GUID что бы не пересекаться.

Таким же образом можно забирать из do блока значения переменных с режимом Out

Oracle 11 SQL
1
2
3
4
5
6
7
8
DO $CODE$
DECLARE cur refcursor := 'transitcursor1'; a INTEGER = 123; b text := 'abc'; c BOOLEAN = NULL;
  BEGIN
   OPEN cur FOR SELECT a, b, c;
  END;
$CODE$ language plpgsql;
 
FETCH ALL FROM  transitcursor1;
Но если у Вас идут простые select, то лучше использовать обычные параметры. Разберитесь как в Вашем API запускать запросы с параметрами.

SQL
1
 SELECT VALUE FROM erz_system_config WHERE description = '333' AND region_id = :regionId AND (:servicepointId IS NULL OR servicepoint_id = :servicepointId) AND (:workstationId IS NULL OR workstation_id = :workstationId);
Кстати блоки с одной функцией так же можно заменить на select даже если функция ни чего не возвращает

Oracle 11 SQL
1
BEGIN perform fnc(:a, :b); END
можно заменить на

Oracle 11 SQL
1
SELECT fnc(:a, :b);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.04.2024, 12:08
Помогаю со студенческими работами здесь

Объявить переменные, для подсчета общего количества предметов для сервировки стола
Объявить переменные, для подсчета общего количества предметов для сервировки стола. (Например чашки, такое же количество блюдец и ложек).

Как объявить переменные для вычисления площади прямоугольника?
Как объявить переменные для вычисления площади прямоугольника?

Как лучше объявить переменную для хранения запроса в винсоке?
Раньше я для запроса создавал переменную так: char *q=(char*)malloc(68); И потом туда данные с помощью sprintf (q,"...");...

Переменные времени для SQL запроса
Здравствуйте уважаемые! Подмогите мозгами, а то совсем растерял за последнее время. Задача такова. Нужно две переменных: ...

Объявить 3 переменные
Объявить 3 переменные. С помощью команд ассемблера переслать данные из 1-ой переменной в 3-ю, из 2-ой в 1-ю из 1-ой во 2-ю и из 2-ой в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru