2012-04-10 1 views
10

Я видел, что можно преобразовать все таблицы к нечувствительны к регистру имен, используя следующие команды в PSQL:Как я могу преобразовать все столбцы в моей базе данных, чтобы нечувствителен к регистру

\o /tmp/go_to_lower 
select 'ALTER TABLE '||'"'||tablename||'"'||' RENAME TO ' || 
lower(tablename)||';' from pg_tables where schemaname = 'public'; 
psql -U username database < /tmp/go_to_lower 

я был не в состоянии чтобы отменить команду для преобразования всех столбцов в регистр без учета регистра таким же образом. Как это можно достичь?

EDIT: По-видимому, указанный выше код преобразует имена таблиц в нижний регистр. Я знаю, что этот код ALTER TABLE «YourTableName» RENAME TO YourTableName; преобразует в регистр без учета регистра имя таблицы. Есть ли способ сделать подобную функцию по массе для имен столбцов?

+1

В случае, если это имеет для вас значение, это не относится к регистру нечувствительно; это преобразование их всех в нижний регистр. –

+0

Он также делает их нечувствительными к регистру, так как при их переименовании нет котировок вокруг имен столбцов. – CSharpened

+0

Вы хотите, чтобы при сопоставлении данных заголовочные ** имена ** не учитывались в регистре или значения столбца ** **? –

ответ

11

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

\t on 
select 'ALTER TABLE '||'"'||table_name||'"'||' RENAME COLUMN '||'"'||column_name||'"'||' TO ' || lower(column_name)||';' 
from information_schema.columns 
where table_schema = 'public' and lower(column_name) != column_name 
\g /tmp/go_to_lower 
\i /tmp/go_to_lower 
+0

Разве это не для одного столбца? – CSharpened

+0

Нет, это для всех. Я обновил макет, чтобы быть более четким, и изменил запрос на более умный (чтобы он не стал пытаться переименовать столбцы уже в нижнем регистре). –

+0

Если вам нужно сделать это для последовательностей: 'select 'ALTER SEQUENCE' || '"' || sequence_name || '"' || ' ИЗМЕНИТЬСЯ К '|| ниже (sequence_name) || ';' from information_schema.sequences где sequence_schema = 'public' и lower (sequence_name)! = sequence_name; ' –

15

По умолчанию все ваши идентификаторы не чувствительны к регистру, а внутренне PostgreSQL хранит их в нижнем регистре. В случае, если вам необходимо иметь:

  • случае чувствительных
  • не-ASCII символов
  • специальных символов

в пределах ваших идентификаторов, вы должны использовать двойные кавычки (") вокруг ваших идентификаторов.

Пожалуйста, проверьте this bit документации PostgreSQL.

EDIT: После вашего разъяснения, вы можете использовать:

SELECT 'ALTER TABLE '||quote_ident(t.relname)||' RENAME TO '||t.relname||';' 
    FROM pg_class t, pg_namespace s 
WHERE s.oid = t.relnamespace AND s.nspname = 'public' 
    AND t.relkind='r' AND t.relname != lower(t.relname) 
ORDER BY 1; 

и столбцов:

SELECT 'ALTER TABLE '||quote_ident(t.relname)|| 
     ' RENAME COLUMN '||quote_ident(a.attname)|| 
     ' TO '||a.attname||';' 
    FROM pg_class t, pg_namespace s, pg_attribute a 
WHERE s.oid = t.relnamespace AND s.nspname = 'public' 
    AND t.relkind='r' 
    AND a.attrelid = t.oid AND NOT a.attisdropped AND a.attnum > 0 
    AND a.attname != lower(a.attname) 
ORDER BY 1; 

Затем скопируйте и вставьте вывод в вашем клиенте.

Если вы используете psql, вы можете использовать \t для включения режима строк только для, \o <full_file_path> сохранить вывод во временный файл и, наконец, \i <full_file_path> выполнить фактические заявления.

+0

Это хорошее объяснение причин проблемы, но на самом деле не решение вопроса OP. –

+2

@ElYobo OP не указывает, в чем проблема. Он намекает в комментарии, что у него проблемы с использованием псевдонима. Похоже, он пытается решить проблему, которая не та, которую он испытывает. –

+0

Возможно, мы читаем другой вопрос, или он был изменен путем редактирования? Я вижу следующее: «Я не смог откопать команду, чтобы преобразовать все столбцы в регистр без учета регистра таким же образом. Как это можно достичь?». –

0
do language plpgsql $$ 
declare 
    r record; 
begin 
    for r in 
     select relname, attname 
     from pg_attribute a 
     inner join pg_class c on a.attrelid = c.oid 
     inner join pg_namespace n on c.relnamespace = n.oid 
     where 
      n.nspname = 'public' 
      and 
      attname != lower(attname) 
      and 
      not attisdropped 
    loop 
     execute format(' 
      alter table %1$I rename column %2$I to %3$s 
     ', r.relname, r.attname, lower(r.attname)); 
    end loop; 
end; 
$$; 

Выдать begin;, прежде чем пытаться это. Проверьте правильность. Только тогда выпустите commit;. Если вы используете пространство имен, то замените его в предложении where.

Смежные вопросы