powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Запрос с подстановкой
20 сообщений из 20, страница 1 из 1
Запрос с подстановкой
    #38429138
Mike359
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
есть запрос, которые отбирает имена таблиц

Код: sql
1.
select table_name from information_schema.columns where column_name='description' AND data_type='character varying'



И есть запрос, которые меняет тип колонки одной таблицы

Код: sql
1.
ALTER TABLE "Epizooticheskaya_situaciya" ALTER COLUMN description TYPE text



Как поменять тип колонки "description" во всех таблицах, которые вернул первый запрос?
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #38429188
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mike359,
анонимный блок, + динамический скл. внутри цикла по выборке из первого запроса.
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #38429208
Mike359
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Мне подсказали такой вариант:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE OR REPLACE FUNCTION test_retype() RETURNS int4 AS 
$BODY$
DECLARE rec RECORD;
BEGIN
FOR rec IN (SELECT table_name from information_schema.columns where column_name='description' AND data_type='character varying') LOOP
ALTER TABLE rec.table_name ALTER COLUMN "description" TYPE text;
END LOOP;
END
$BODY$ 
LANGUAGE plpgsql VOLATILE
cost 100;



В PostgreSQL 9.1 все работает, но в нужная мне база 8.4, и там это выражение вызывает ошибку

ОШИБКА: ошибка синтаксиса (примерное положение: "$1")
LINE 1: ALTER TABLE $1 ALTER COLUMN "description" TYPE text

Почему так?
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #38429284
Гость_0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mike359,

потому что в 8.4 нельзя использовать имя таблицы как параметр, вызывайте ALTER через EXECUTE.
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #38429313
Mike359
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо. Итоговый вариант для будущих поколений:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE OR REPLACE FUNCTION test_retype() RETURNS int4 AS 
$BODY$
DECLARE rec RECORD;
BEGIN
FOR rec IN (SELECT table_name from information_schema.columns where column_name='description' AND data_type='character varying') LOOP
EXECUTE 'ALTER TABLE "'|| rec.table_name||'" ALTER COLUMN "description" TYPE text';
END LOOP;
RETURN 1;
END
$BODY$ 
LANGUAGE plpgsql VOLATILE

cost 100;

SELECT test_retype() ;
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Запрос с подстановкой
    #39454442
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите, пожалуйста, что я делаю не так? PostgreSQL версия 9.5
Хочу всем таблицам базы изменить схему. Перепробовал 4 варианта. Первый подсмотрен тут ругается на Alter. Все остальные уверяют меня, что таблица не существует.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
DO $$
DECLARE tname regclass;
declare sql text;
begin
while exists(select table_name
  from information_schema.columns 
  where table_schema='public') loop

  select table_name into tname
  from information_schema.columns 
  where table_schema='public' FETCH FIRST 1 ROWS ONLY;

-- вариант 1
--  EXECUTE format($$ ALTER TABLE %I SET SCHEMA rent $$, tname);

-- вариант 2  
--  sql := 'alter TABLE '||tname||' set SCHEMA rent';
--  EXECUTE sql;

-- вариант 3
/*  sql := 'alter TABLE "'||tname||'" set SCHEMA rent';
  EXECUTE sql;
*/
-- вариант 4
  sql := 'alter TABLE %I set SCHEMA rent';
  EXECUTE format(sql,tname);

end LOOP;
end $$
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454500
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexeyd,

опуская странный выбор колумнсов, вместо теблсов, (да и сам стиль говнокодинга, у меня всё работает. во всех вариантах.
думаю, вы пытаетесь сделать что--то лишнее
, например эту гадость выполнять конкурентно.
пишите ошибки полнее.

[SRC sqlBEGIN;
DO $$
DECLARE tname regclass;
--DECLARE tname text;
declare sql text;
begin
while exists(select table_name
from information_schema.columns
where table_schema='public') loop

select table_name into tname
from information_schema.columns
where table_schema='public' FETCH FIRST 1 ROWS ONLY;

-- вариант 1
--EXECUTE format($e$ ALTER TABLE %I SET SCHEMA rent $e$, tname);

-- вариант 2
--sql := 'alter TABLE '||tname||' set SCHEMA rent'; EXECUTE sql;

-- вариант 3
--sql := 'alter TABLE "'||tname||'" set SCHEMA rent';EXECUTE sql;

-- вариант 4
sql := 'alter TABLE %I set SCHEMA rent';EXECUTE format(sql,tname);

end LOOP;
end $$;

select table_name
from information_schema.columns
where table_schema='rent';
---смотрим список табличек
rollback;
[/SRC]
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454556
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Ошибка для варианта 1
ОШИБКА: ошибка синтаксиса (примерное положение: "ALTER")
LINE 14: EXECUTE format($$ ALTER TABLE %I SET SCHEMA rent $$, tname...


Ошибка для вариантов 2-4
ОШИБКА: отношение "limitobject" не существует
CONTEXT: функция PL/pgSQL inline_code_block, строка 9, оператор SQL-оператор


qwwqопуская странный выбор колумнсов, вместо теблсов
Это то, что первое нагуглилось, после опубликования вопроса, догадался, что можно использовать information_schema.tables. Правда результат от этого не изменился. Может какие-то дополнительные настройки самого ПостГри требуются? У меня всё по-дефолту после установки.

Это первый опыт работы с Postgre(откровенно говоря, после МС СКЛ он мне очень не нравится), потому прошу также подсказать, что не так со стилем кода?
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454585
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Упс, похоже проблема в таблице limitobject. Стоило перенести таблицу вручную, код заработал. Экспериментальным методом научного тыка, выяснил, что к ней надо обращаться через полный путь - схема.limitobject иначе - ни в какую, даже после ее переименования "abc".
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454595
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexeyd,

1 вы невнимательны. /*перечитайте мой предыдущий спойлер.*/

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



попробуйте это и только это
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
BEGIN;
DO $d$
	DECLARE tname regclass;
	--DECLARE tname text;
	
	begin
		FOR tname IN select quote_ident(table_name)
			  from information_schema."tables"
			  where table_schema='public' 
		loop 
			EXECUTE format($e$ ALTER TABLE %I SET SCHEMA rent $e$, tname);
		end LOOP;
	end
$d$;

select table_name
  from information_schema."tables"
  where table_schema='rent';
--rollback;

...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454633
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq, подождите, в скрипте все варианты, кроме одного комментились. Исполнялся только чистый эксперимент с одним вариантом.
Никаких транзакций и прочего - только 1 приведённый мной скрипт, который выполнялся в редакторе запросов и всё - база только проектируется.
Таблиц с пробелами, подчёркиваниями и прочим не имеется - все названия в одно слово.
Разве язык pl/pgsql регистрозависимый? Зачем квотить имена, написанные в смешанном регистре?
Мой вариант с вашими поправками: вместо $$ написать $e$ сработал.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
DO $$
DECLARE tname regclass;

begin
while exists(select table_name
  from information_schema.tables
  where table_schema='public') loop

  select table_name into tname
  from information_schema.tables
  where table_schema='public' FETCH FIRST 1 ROWS ONLY;

EXECUTE format($e$ ALTER TABLE %I SET SCHEMA rent $e$, tname);

end LOOP;
end $$



Прошу еще пояснить, почему если я оставляю запрос таким, каким он был изначально, включая комментарии, появляется ругань?
ОШИБКА: ошибка синтаксиса (примерное положение: "ALTER")
LINE 14: EXECUTE format($$ ALTER TABLE %I SET SCHEMA rent $$, tname...


Ведь эта строчка закомменчена. При этом, если перенести её за пределы блока DO (после end $$), ошибка исчезает.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
DO $$
DECLARE tname regclass;
declare sql text;
begin
while exists(select table_name
  from information_schema.columns 
  where table_schema='public') loop

  select table_name into tname
  from information_schema.columns 
  where table_schema='public' FETCH FIRST 1 ROWS ONLY;

-- вариант 1
--  EXECUTE format($$ ALTER TABLE %I SET SCHEMA rent $$, tname);

-- вариант 2  
--  sql := 'alter TABLE '||tname||' set SCHEMA rent';
--  EXECUTE sql;

-- вариант 3
/*  sql := 'alter TABLE "'||tname||'" set SCHEMA rent';
  EXECUTE sql;
*/
-- вариант 4
  sql := 'alter TABLE %I set SCHEMA rent';
  EXECUTE format(sql,tname);

end LOOP;
end $$

...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454642
ursido
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexeydПрошу еще пояснить, почему если я оставляю запрос таким, каким он был изначально, включая комментарии, появляется ругань?


Потому что RTFM . Вы используете один и тот же символ ($$) для квотирования тела функции и строки внутри тела функции. Поэтому интерпретатор полагает, что функция заканчивается именно в этом месте, а дальше идет какая-то ересь. О чем и сообщает обычным английским языком.
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454683
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ursidoВы используете один и тот же символ ($$) для квотирования тела функции и строки внутри тела функции. Поэтому интерпретатор полагает, что функция заканчивается именно в этом месте, а дальше идет какая-то ересь.
Жаль, что его не научили а) выполнять операции без лишнего квотирования; б) игнорировать комментарии.
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454698
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexeydursido<>
Жаль, что его не научили а) выполнять операции без лишнего квотирования;

мальчик, ты дебил
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454713
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqмальчик, ты дебил
Очень информативно. За это огромное вам спасибо.
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454734
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexeydqwwqмальчик, ты дебил
Очень информативно. За это огромное вам спасибо.
альтернативно одаренным даю наводку:

помедитируйте об эскепинге спецсимволов в строковых литералах в коде
самое простое
Код: sql
1.
'это литерал включающий одинарную кавычку '' '
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454759
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqпомедитируйте об эскепинге спецсимволов в строковых литералах в коде
самое простое
Код: sql
1.
'это литерал включающий одинарную кавычку '' '


Если этот литерал с одинарной кавычкой будет закомменчен, ни один компилятор не придерётся, кроме Постгришного.
МС спокойно относится к наличию стапятисот незакрытых кавычек в комментариях.
Код: sql
1.
2.
3.
4.
5.
6.
SELECT * FROM CostAttributeslink AS cac
JOIN CostAttributes AS ca
    ON ca.CostAttributes = cac.CostAttributes
WHERE ca.DateBegin>='20160101' --'''
/*'*/
--'



А вообще, я имел в виду, что дурацкие доллары, блоки Do - всё это лишнее, у МС в этом плане намного удачнее реализация.
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454798
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexeydЕсли этот литерал с одинарной кавычкой будет закомменчен, ни один компилятор не придерётся, кроме Постгришного.
МС спокойно относится к наличию стапятисот незакрытых кавычек в комментариях.


гм:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select 1 as f --''' 
/*
'
*/
;
---------------------------
Total query runtime: 12 msec
1 строка получена.



а вы ещё более альтернативны, чем я полагал
как любили говорить в раньшие года -- днище

или вы и там снизу постучите ?


квотирование литералов не кавычками , а дабл-бакс-тагами $tag$ -- альтернативный способ, и вы можете его даже отключить, а не только не пользоваться. продолжайте юзать кавычки и их удваивать на каждом уровне - если вам от этого легче
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454804
Alexeyd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqможете его даже отключить
С удовольствием это сделаю, если расскажете как. Да, я предпочту удвоение кавычек а-ля Т-СКЛ - мне не сложно.
...
Рейтинг: 0 / 0
Запрос с подстановкой
    #39454837
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexeyd если расскажете как
RTFM
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Запрос с подстановкой
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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