Как выбрать столбец (столбцы) по их числовому положению в таблице?

Я пытаюсь выбрать столбцы по их положению "x" в таблице.

ДБИ

my $example = $hookup->prepare(qq{SELECT This,That,Condition,"I also want COLUMN-10" FROM tbl LIMIT ? ?});

    ###column_number=10 ordinal_position?? 
    $example->execute('2','10') or die "Did not execute";

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

Одна проблема, с которой я столкнулся, была с столбцом под названием «Условие». По какой-то причине, когда я пытался select Condition, выполнение умирало. Я никогда не пытался, но что, если имя столбца было SELECT?

Еще одно замечание: таблица имеет ширину 75 столбцов, а мне нужно только 50 из них. Имена Col довольно многословны, поэтому я хотел бы просто называть их по их «позиции». Это также позволит изменить имена столбцов в будущем без необходимости изменять оператор выбора.

Я совсем новичок, поэтому, пожалуйста, объясните любые ответы на моем уровне. Спасибо за любую помощь..


person DulcimerDude    schedule 01.01.2011    source источник
comment
PS смещение строки 2 10 не имеет отношения, просто для тестирования.   -  person DulcimerDude    schedule 01.01.2011


Ответы (3)


Вы могли бы прочитать COLUMNS.ORDINAL_POSITION (см. здесь), но это похоже на грядущую катастрофу.

Вы можете (и всегда должны!) заключать имена столбцов в кавычки, например SELECT `colname`. Это будет обрабатывать случаи, когда имена таблиц будут Condition или SELECT.

person moinudin    schedule 01.01.2011
comment
Спасибо. Ваш ответ был полезен. Указание на использование кавычек исправило одну из моих проблем. Первое, чему я научился в этом году!!! - person DulcimerDude; 01.01.2011
comment
@marcog - это не совсем правильно. Столбцы имеют определенные позиции в конкретных реализациях сервера баз данных (возможно, ВСЕ из них), даже если эта позиция не является частью теоретического реляционного исчисления, лежащего в основе указанных реализаций. К тому же почти каждый сервер базы данных создает таблицы с оператором, последовательно перечисляющим столбцы, и большинство хранит информацию об этой таблице в специальной таблице столбцов таблиц, которая имеет упорядоченный числовой идентификатор для каждого столбца в правильном порядке. - person DVK; 01.01.2011
comment
@marcog - это, конечно, не умаляет того факта, что вы почти НИКОГДА не должны полагаться на номер столбца в таблице в любом своем коде (если только по какой-либо другой причине, кроме как кто-то всегда может ИЗМЕНИТЬ таблицу и вставить столбец в начало/середина) - person DVK; 01.01.2011
comment
@DVK Является ли порядок детерминированным или вы можете получить доступ к специальной таблице? - person moinudin; 01.01.2011
comment
@DVK Действительно, я думаю, что ORDINAL_POSITION в INFORMATION_SCHEMA.COLUMNS является частью какого-то стандарта (ANSI?) - person Martin Smith; 01.01.2011
comment
@DVk, @Martin information_schema действительно делает метаданные доступными. Хорошо ли читать эти метаданные? - person moinudin; 01.01.2011
comment
@marcog - Если вы не переписываете какой-либо инструмент администратора, вероятно, нет. Я просто указываю, что это существует. - person Martin Smith; 01.01.2011
comment
@Мартин Вот что я подозревал. - person moinudin; 01.01.2011
comment
@marcog - см. мой ответ ниже. Короткий ответ: да, можно, нет, не стоит :) - person DVK; 01.01.2011

Вы почти НИКОГДА не должны полагаться на номер столбца в таблице в любом своем коде (даже если теоретически вы МОЖЕТЕ сделать это технически).

Есть много причин, одна из самых важных заключается в том, что кто-то всегда может ИЗМЕНИТЬ таблицу и вставить столбец в начало/середину, полностью сломав ваш код.

Вторая причина заключается в том, что позиции столбцов — даже если вы предполагаете, что таблица никогда не меняется — делают код абсолютно НЕЧИТАЕМЫМ и, следовательно, невозможным его сопровождение. Вы помните, что столбец 13 был «last_name_3» через 2 года?

Обратите внимание, что если ваша проблема заключается в том, что, например, у вас в коде есть что-то вроде SELECT fn11, fn12, fn13, ... fn32, и вы чувствуете, что написать fn11..fn32 — это перетаскивание, вы не только правы на 100%, но вам следует полностью удалить указанное перетаскивание через Perl. идиомы, например: "SELECT " . join(", ", map { "fn$_" } (11..32));


Сказав это, если вы хотите знать, как это сделать ТЕОРЕТИЧЕСКИ, просто как упражнение «крутой технологический трюк», я не знаю хорошего способа сделать это в общем через DBI, но обычно вы можете сделать это в базе данных - специфический способ.

Для этого следует учесть, что:

  1. Практически ВСЕ базы данных создают таблицы с помощью своего рода оператора «CREATE TABLE», который принимает ORDERED список столбцов (большинство реляционных баз данных фактически физически хранят значения в строке в этом порядке, поэтому это важно — даже если теоретическое реляционное исчисление рассматривает столбцы как упорядоченные). меньше, как сказал Марког).

  2. Практически ВСЕ базы данных содержат специальную таблицу, в которой указано, какие таблицы содержат какие столбцы (syscolumns в Sybase, INFORMATION_SCHEMA.COLUMNS в MySQL), и эта таблица содержит числовой идентификатор столбца, который используется для их упорядочения так же, как "создать" порядок; или даже специальное поле «порядок» (например, значение ORDINAL_POSITION в MySQL).

    Таким образом, вы можете заранее запросить упорядоченный список столбцов для нужной вам таблицы и их порядок. Чтобы запросить MySQL, SELECT COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="XXX" . Сохраните данные в списке @columns (или, если у вас много таблиц, хэш массивов, %columns, с именем таблицы в качестве ключа).

    Затем при построении запроса вы просто говорите

    "select $columns{table1}->[11],$columns{table1}->[13], ...."

    Обратите внимание, что фактический SQL-код, отправляемый на сервер, будет содержать имена столбцов, НО вы не будете жестко кодировать эти имена где-либо в своем коде.

person DVK    schedule 01.01.2011
comment
Обратите внимание, что этот ответ относится только к РЕЛЯЦИОННЫМ базам данных. Вполне возможно, хотя маловероятно, что некоторые/все нереляционные БД на самом деле не имеют определенного или доступного порядка столбцов - как я уже сказал, это зависит от сервера БД. - person DVK; 01.01.2011

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

Это сообщает вам имя столбца, если у вас есть только позиция, например, если вы знаете, что это только 3rd позиция...

SELECT COLUMN_NAME
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'YourSchema'
AND TABLE_NAME = 'YourTable' AND 
ORDINAL_POSITION = 3;

Естественно, вы думаете, что можете просто обернуть это в SELECT (subqueryabove) FROM YourTable, но не будете, потому что вашим результатом будет эта константа: YourField, а не значение в реальных строках. Таким образом, это даже невозможно сделать в одном запросе. Конечно, вы могли бы использовать переменные, но тогда это решение становится все более сложным, и теперь вы должны понять, почему запрашивать поля не очень хорошая идея. исходя из их положения.

Взгляните на MySQL.com: объект схемы< /strong> Документация по именам:

Определенные объекты в MySQL, включая базу данных, таблицу, индекс, столбец, псевдоним, представление, хранимую процедуру, раздел, табличное пространство, группу ресурсов и другие имена объектов, известны как идентификаторы....

Идентификатор может быть заключен в кавычки или не заключен в кавычки. Если идентификатор содержит специальные символы или является зарезервированным словом, вы должны заключать его в кавычки всякий раз, когда ссылаетесь на него.

Я подозреваю, что вы просто хотите что-то, что цитируется. В этом случае используйте обратные кавычки. Также из вышеуказанного источника...

mysql> SELECT * FROM `select` WHERE `select`.id > 100;
person HoldOffHunger    schedule 05.11.2020