2012-04-16 2 views
6

Предположив запрос, такие как:Prepend текст MySQL колонны имена

SELECT * FROM tableA; 

Как я могу PREPEND a_ для каждого столбец имени? Например, если есть столбец «имя пользователя», он будет доступен в результатах как «a_username».

EDIT: Формат SELECT username AS a_username не поможет, как мне нужно, чтобы продолжить использование выбор в * поле. Существует JOIN и потенциальный конфликт с возвращенным столбцом из другой таблицы в JOIN. Я буду перебирать возвращаемые столбцы (foreach) и хочу только выводить столбцы, которые пришли из конкретной таблицы (схема которой может измениться), в поля ввода HTML, где администратор сайта может напрямую редактировать содержимое полей. Предложенный SQL-запрос выглядит как SELECT firstTable.*, anotherTable.someField, anotherTable.someOtherField, и существует возможность существования someField или someOtherField в firstTable.

Спасибо.

+0

Зачем вам ['SELECT *'] (http://stackoverflow.com/q/321299/)? Это, как правило, плохая практика, если вы не пишете программу администрирования БД. – outis

+0

@outis: Фактически, этот код предоставляет администратору форума возможность напрямую изменять значения в пользовательской таблице, которая может иметь или не иметь дополнительных полей, добавленных к ней в будущем. Я также ненавижу использование «SELECT *», но, как вы заявляете, он оправдан и предпочтительнее в этом случае использования. – dotancohen

+0

Мне любопытно, почему это когда-нибудь понадобится: что не так с именами оригинальных столбцов? – eggyal

ответ

10

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

Сначала давайте создадим пример базы данных называется dotancohen и таблица называется mytable

mysql> drop database if exists dotancohen; 
Query OK, 1 row affected (0.03 sec) 

mysql> create database dotancohen; 
Query OK, 1 row affected (0.00 sec) 

mysql> use dotancohen 
Database changed 
mysql> create table mytable 
    -> (
    ->  id int not null auto_increment, 
    ->  username varchar(30), 
    ->  realname varchar(30), 
    ->  primary key (id) 
    ->); 
Query OK, 0 rows affected (0.06 sec) 

mysql> insert into mytable (realname,username) values 
    -> ('rolando','odnalor'),('pamela','alemap'), 
    -> ('dominique','euqinimod'),('diamond','dnomaid'); 
Query OK, 4 rows affected (0.05 sec) 
Records: 4 Duplicates: 0 Warnings: 0 

mysql> select * from mytable; 
+----+-----------+-----------+ 
| id | username | realname | 
+----+-----------+-----------+ 
| 1 | odnalor | rolando | 
| 2 | alemap | pamela | 
| 3 | euqinimod | dominique | 
| 4 | dnomaid | diamond | 
+----+-----------+-----------+ 
4 rows in set (0.00 sec) 

mysql> 

Вот таблица метаданных называется INFORMATION_SCHEMA.КОЛОННЫ:

mysql> desc INFORMATION_SCHEMA.COLUMNS; 
+--------------------------+---------------------+------+-----+---------+-------+ 
| Field     | Type    | Null | Key | Default | Extra | 
+--------------------------+---------------------+------+-----+---------+-------+ 
| TABLE_CATALOG   | varchar(512)  | NO |  |   |  | 
| TABLE_SCHEMA    | varchar(64)   | NO |  |   |  | 
| TABLE_NAME    | varchar(64)   | NO |  |   |  | 
| COLUMN_NAME    | varchar(64)   | NO |  |   |  | 
| ORDINAL_POSITION   | bigint(21) unsigned | NO |  | 0  |  | 
| COLUMN_DEFAULT   | longtext   | YES |  | NULL |  | 
| IS_NULLABLE    | varchar(3)   | NO |  |   |  | 
| DATA_TYPE    | varchar(64)   | NO |  |   |  | 
| CHARACTER_MAXIMUM_LENGTH | bigint(21) unsigned | YES |  | NULL |  | 
| CHARACTER_OCTET_LENGTH | bigint(21) unsigned | YES |  | NULL |  | 
| NUMERIC_PRECISION  | bigint(21) unsigned | YES |  | NULL |  | 
| NUMERIC_SCALE   | bigint(21) unsigned | YES |  | NULL |  | 
| CHARACTER_SET_NAME  | varchar(32)   | YES |  | NULL |  | 
| COLLATION_NAME   | varchar(32)   | YES |  | NULL |  | 
| COLUMN_TYPE    | longtext   | NO |  | NULL |  | 
| COLUMN_KEY    | varchar(3)   | NO |  |   |  | 
| EXTRA     | varchar(27)   | NO |  |   |  | 
| PRIVILEGES    | varchar(80)   | NO |  |   |  | 
| COLUMN_COMMENT   | varchar(1024)  | NO |  |   |  | 
+--------------------------+---------------------+------+-----+---------+-------+ 
19 rows in set (0.02 sec) 

mysql> 

Что вам нужно из этой таблицы следующие столбцы:

  • table_schema
  • table_name
  • column_name
  • ORDINAL_POSITION

Что вы просите должен иметь имя column_ и column_name предваряется a_

Вот запрос и как выполнить его:

select concat('select ',column_list,' from ',dbtb) into @newsql 
from (select group_concat(concat(column_name,' a_',column_name)) column_list, 
concat(table_schema,'.',table_name) dbtb from information_schema.columns 
where table_schema = 'dotancohen' and table_name = 'mytable' 
order by ordinal_position) A; 
select @newsql; 
prepare stmt from @newsql; 
execute stmt; 
deallocate prepare stmt; 

Давайте выполним его

mysql> select concat('select ',column_list,' from ',dbtb) into @newsql 
    -> from (select group_concat(concat(column_name,' a_',column_name)) column_list, 
    -> concat(table_schema,'.',table_name) dbtb from information_schema.columns 
    -> where table_schema = 'dotancohen' and table_name = 'mytable' 
    -> order by ordinal_position) A; 
Query OK, 1 row affected (0.01 sec) 

mysql> select @newsql; 
+--------------------------------------------------------------------------------+ 
| @newsql                  | 
+--------------------------------------------------------------------------------+ 
| select id a_id,username a_username,realname a_realname from dotancohen.mytable | 
+--------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> prepare stmt from @newsql; 
Query OK, 0 rows affected (0.00 sec) 
Statement prepared 

mysql> execute stmt; 
+------+------------+------------+ 
| a_id | a_username | a_realname | 
+------+------------+------------+ 
| 1 | odnalor | rolando | 
| 2 | alemap  | pamela  | 
| 3 | euqinimod | dominique | 
| 4 | dnomaid | diamond | 
+------+------------+------------+ 
4 rows in set (0.01 sec) 

mysql> deallocate prepare stmt; 
Query OK, 0 rows affected (0.00 sec) 

mysql> 

Дайте ему попробовать !!!

Вы упомянули в своем вопросе: Формат имени пользователя SELECT username AS a_username не поможет, поскольку мне нужно продолжить использование выбора поля *.

Все, что вам нужно сделать, чтобы реализовать свое предложение выполняется запрос с использованием TABLEA следующим образом:

select concat('select ',column_list,' from ',dbtb) into @newsql 
from (select group_concat(concat(column_name,' a_',column_name)) column_list, 
concat(table_schema,'.',table_name) dbtb from information_schema.columns 
where table_schema = DATABASE() and table_name = 'tableA' 
order by ordinal_position) A; 

При получении этого результата запроса, просто использовать его в качестве запроса представить mysql_query.

+0

Большое спасибо Роландо. Я многое узнал из вашего ответа, не в последнюю очередь, о том, что решение, которое подходит для моих целей, не существует. Тем не менее, ваши образцовые и продуманные примеры научили меня точно, почему, и это ответ _real_. Я ценю вашу помощь и ваш совет! – dotancohen

3

Вам необходимо перечислить столбцы, например

SELECT username AS a_username FROM tableA; 

в качестве альтернативы, пост-процесс в фоновом, например, изменение ключей массива в коде

+1

Это работает только для одного столбца. У меня есть 22 столбца в этой конкретной таблице, и есть несколько запросов. Поэтому мне нужно сохранить формат «SELECT *». – dotancohen

+3

удачи, либо перечислите их все, либо измените ключи массива в фоновом режиме – scibuff

+0

Вы можете перечислить несколько с помощью формата «select ... as» --- как выберите имя пользователя как a_username, другое поле как a_otherfield, другое поле - как a_anotherfield. .. – Kasapo

0

Я не считаю, что это может быть сделано для всех столбцов автоматически, но вы можете перечислить столько столбцов, как вам нравится с AS

SELECT id AS a_id, 
     name AS a_name, 
     email AS a_email /*, etc....*/ 
FROM tableA; 

Я только вставить новые строки для некоторой дополнительной ясности.

+0

Спасибо, Алистер. Я уточнил вопрос, чтобы выяснить, что выбор поля '*' должен быть сохранен. – dotancohen

1

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

Но если вы действительно этого хотели, вы могли бы написать хранимую процедуру, которая запрашивала бы информацию_информации, чтобы получить список столбцов в таблице, а затем префикс их один за другим. После этого можно связать запрос как строку, PREPARE и EXECUTE.

Недостатком этого подхода является тот факт, что вы не можете присоединиться к результату хранимой процедуры. Но, конечно же, вы могли бы создать хранимую процедуру для каждого типа запросов, которые вы выдаете. Префикс полей для любой таблицы можно затем сделать отдельным общим FUNCTION.

Все это звучит для меня как перебор. Я бы рекомендовал переименовать фактические столбцы, чтобы они всегда были префиксом или просто перечисляли все поля результатов с помощью псевдонимов AS, как предложено Scibuff и Alister.

+0

Спасибо, Шедал. Как вы говорите, нельзя «ПРИСОЕДИНЯЙСЯ» в хранимой процедуре, и это именно «JOIN», что мне нужно сделать. – dotancohen

2

Создайте представление с переименованными столбцами, например. -

CREATE VIEW a_view AS SELECT username AS a_username FROM table; 

Затем обратитесь к этому представлению.

+0

Спасибо Деварт. Представление недостаточно гибко для конкретной ситуации, с которой мне нужно работать. – dotancohen

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