2012-04-16 11 views
6

Przypuśćmy zapytanie takie jak:Prepend tekst do mysql kolumny nazw

SELECT * FROM tableA; 

Jak można poprzedzić a_ każdemu kolumnach nazwy? Na przykład, jeśli jest kolumna "nazwa użytkownika", byłby on dostępny w wynikach jako "a_username".

EDIT: sformatować SELECT username AS a_username nie pomoże jak muszę kontynuować korzystanie wybór * pola. Istnieje JOIN i potencjalny konflikt ze zwróconą kolumną z innej tabeli w JOIN. Będę iterować nad zwróconymi kolumnami (foreach) i chcę tylko wyprowadzać kolumny, które pochodziły z konkretnej tabeli (której schemat może się zmieniać) na pola wejściowe HTML, w których administrator strony mógłby bezpośrednio edytować zawartość pól. Zapytanie SQL, o którym mowa, wygląda jak SELECT firstTable.*, anotherTable.someField, anotherTable.someOtherField, a istnieje ich możliwość, że someField lub someOtherField istnieje w firstTable.

Dzięki.

+0

Dlaczego potrzebujesz ['SELECT *'] (http://stackoverflow.com/q/321299/)? Zasadniczo jest to zła praktyka, chyba że piszesz program administracyjny DB. – outis

+0

@outis: W rzeczywistości ten kod zapewnia administratorowi forum możliwość bezpośredniej zmiany wartości w niestandardowej tabeli, która może, ale nie musi zawierać dodatkowe pola dodane w przyszłości. Poza tym brzydzę się używaniem słowa "SELECT *", ale w tym przypadku jest to uzasadnione i pożądane. – dotancohen

+0

Jestem ciekawy, dlaczego ktoś kiedykolwiek musiałby to zrobić: co jest nie tak z oryginalnymi nazwami kolumn? – eggyal

Odpowiedz

10

Możesz użyć tabeli INFORMATION_SCHEMA.COLUMNS do sformułowania zapytania, a następnie użyć dynamicznego SQL do jego wykonania.

Najpierw zróbmy przykładową bazę danych o nazwie dotancohen i stół zwany 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> 

Oto tabela metadanych nazywany INFORMATION_SCHEMA.Kolumny:

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> 

Co trzeba z tej tabeli są następujące kolumny:

  • TABLE_SCHEMA
  • table_name
  • column_name
  • ORDINAL_POSITION

co prosicie jest mieć column_name i column_name poprzedzane a_

Oto zapytanie i jak to wykonać:

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; 

Niech go wykonać

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> 

spróbować !!!

Wspomniałeś w swoim pytaniu: Format nazwy użytkownika jako AS_nazwa_użytkownika nie pomoże, ponieważ potrzebuję kontynuować korzystanie z pola wyboru *.

Wszystko co musisz zrobić, aby wdrożyć moja propozycja jest uruchomić kwerendę za pomocą TABLEA następująco:

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; 

Podczas pobierania tego rezultatu zapytania, wystarczy użyć go jako zapytanie do przedstawienia mysql_query.

+0

Dziękuję bardzo Rolando. Wiele nauczyłem się z twojej odpowiedzi, a przynajmniej nie jest to, że rozwiązanie, które pasuje do moich celów, nie istnieje. Jednak twoje przykładne i wyszukane przykłady nauczyły mnie dokładnie, dlaczego, i to jest prawdziwa odpowiedź. Doceniam twoją pomoc i twoją radę! – dotancohen

3

Musisz listy kolumn, np

SELECT username AS a_username FROM tableA; 

alternatywnie, post-proces w back-end, np zmienić klucze tablicy w kodzie

+1

Działa to tylko dla pojedynczej kolumny. Mam 22 kolumny w tej konkretnej tabeli i istnieje wiele zapytań. Dlatego muszę zachować format "SELECT *". – dotancohen

+3

trudno, albo wymień je wszystkie, albo zmień klucze tablicy na zapleczu. – scibuff

+0

Możesz podać wiele za pomocą formatu "wybierz ... jako" --- np. wybierz nazwę użytkownika jako nazwa_użytkownika, pole_własne jako pole_za_powietrze, drugie pole jako pole_inne. .. – Kasapo

0

nie wierzę, może być automatycznie wykonywane dla wszystkich kolumn, ale można wymienić tyle kolumn, ile chcesz z AS

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

mam włożyć tylko nowe linie dla dodatkowej przejrzystości.

+0

Dzięki, Alister. Wyjaśniłem pytanie, aby wyjaśnić, że selekcja pola "*" musi zostać zachowana. – dotancohen

1

Jak już wspomniano, nie ma standardowego sposobu na masową prefiks nazwy kolumn w regularnych zapytań.

Ale jeśli naprawdę chcesz to osiągnąć, możesz napisać procedurę przechowywaną, która zapyta information_schema, aby uzyskać listę kolumn w tabeli, a następnie przedrostek jeden po drugim. Następnie można połączyć zapytanie jako ciąg, PREPARE i EXECUTE.

Wadą takiego podejścia jest fakt, że nie można dołączyć do wyniku procedury przechowywanej. Oczywiście można również utworzyć procedurę składowaną dla każdego typu zapytania, które wydajesz. Poprzedzenie pól dla dowolnej tabeli można następnie przekształcić w oddzielny ogólny kod FUNCTION.

Wszystko to jednak brzmi jak przesada. Polecam albo zmianę nazwy rzeczywistych kolumn, tak aby były one zawsze prefiksowane, albo po prostu wyświetlanie wszystkich pól wyników z aliasami AS, jak zasugerowali Scibuff i Alister.

+0

Dziękuję Shedal. Jak wspomniałeś, nie można "JOIN" na procedurze przechowywanej i jest to dokładnie "JOIN", które muszę zrobić. – dotancohen

2

Utwórz widok z kolumnami o zmienionej nazwie, np. -

CREATE VIEW a_view AS SELECT username AS a_username FROM table; 

Następnie przejdź do tego widoku.

+0

Dziękuję Devart. Widok nie jest wystarczająco elastyczny dla konkretnej sytuacji, z którą muszę pracować. – dotancohen