Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Запрос с подстановкой / 20 сообщений из 20, страница 1 из 1
16.10.2013, 09:14
    #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
16.10.2013, 10:07
    #38429188
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос с подстановкой
Mike359,
анонимный блок, + динамический скл. внутри цикла по выборке из первого запроса.
...
Рейтинг: 0 / 0
16.10.2013, 10:23
    #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
16.10.2013, 11:03
    #38429284
Гость_0
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос с подстановкой
Mike359,

потому что в 8.4 нельзя использовать имя таблицы как параметр, вызывайте ALTER через EXECUTE.
...
Рейтинг: 0 / 0
16.10.2013, 11:20
    #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
Период между сообщениями больше года.
17.05.2017, 11:06
    #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
17.05.2017, 11:52
    #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
17.05.2017, 12:49
    #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
17.05.2017, 13:11
    #39454585
Alexeyd
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос с подстановкой
Упс, похоже проблема в таблице limitobject. Стоило перенести таблицу вручную, код заработал. Экспериментальным методом научного тыка, выяснил, что к ней надо обращаться через полный путь - схема.limitobject иначе - ни в какую, даже после ее переименования "abc".
...
Рейтинг: 0 / 0
17.05.2017, 13:17
    #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
17.05.2017, 13:56
    #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
17.05.2017, 14:01
    #39454642
ursido
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос с подстановкой
AlexeydПрошу еще пояснить, почему если я оставляю запрос таким, каким он был изначально, включая комментарии, появляется ругань?


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

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

помедитируйте об эскепинге спецсимволов в строковых литералах в коде
самое простое
Код: sql
1.
'это литерал включающий одинарную кавычку '' '
...
Рейтинг: 0 / 0
17.05.2017, 15:18
    #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
17.05.2017, 15:54
    #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
17.05.2017, 16:02
    #39454804
Alexeyd
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос с подстановкой
qwwqможете его даже отключить
С удовольствием это сделаю, если расскажете как. Да, я предпочту удвоение кавычек а-ля Т-СКЛ - мне не сложно.
...
Рейтинг: 0 / 0
17.05.2017, 16:33
    #39454837
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос с подстановкой
Alexeyd если расскажете как
RTFM
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Запрос с подстановкой / 20 сообщений из 20, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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