如何通过表中的“数字”位置选择列?

时间:2011-01-01 17:56:34

标签: mysql perl

我正在尝试按表中的“x”位置选择列。

DBI

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";

这是可能的还是我需要再运行另一个选择?

我遇到的一个问题是名为“条件”的col。出于某种原因,当我尝试select Condition时,执行会死亡。我从未尝试过,但如果列名是SELECT,该怎么办?

另一个注意事项是桌子宽75 col,我只需要50。。 Col名称非常详细,所以我想通过他们的“位置”来称呼它们。这样也可以在将来更改列名,而无需更改select语句。

我是新手,所以请将任何答案解释到我的水平。谢谢你的帮助......

3 个答案:

答案 0 :(得分:2)

你几乎不应该依赖任何代码中表格中的列号(即使理论上你理论上也可以这样做)。

有很多原因,其中一个最重要的原因是有人可以随时更改表并在开头/中间插入一列,完全破坏您的代码。

第二个原因是列位置 - 即使你假设表永远不会改变 - 使得绝对无法进行,因此无法维护代码。你还记得第二列是从现在起2年后的“last_name_3”吗?

请注意,如果您的问题是,例如您的代码中有SELECT fn11, fn12, fn13, ... fn32这样的内容,并且您觉得拼写fn11..fn32是一个拖累,那么您不仅100%正确,而且您绝对应该通过Perl惯用法删除所述拖拽,如下所示:"SELECT " . join(", ", map { "fn$_" } (11..32));


话虽如此,如果你想知道怎么做理论,就像一个“酷炫的技巧”练习,我不知道通过DBI一般性地做到这一点的好方法,但你通常可以这样做以特定于数据库的方式。

为此,您应该注意:

  1. 几乎所有数据库都通过某种“CREATE TABLE”语句创建表,该语句采用ORDERED列列表(大多数关系数据库实际上按行顺序存储行中的值,因此它很重要 - 即使理论关系也是如此微积分将列视为无序,如marcog所说。

  2. 几乎ALL da; tabases包含一个特殊的表,列出哪些表包含哪些列(Sybase中为syscolumns,MySQL中为INFORMATION_SCHEMA.COLUMNS),该表包含列的数字ID用于命令它们与“创建”命令相同;甚至特殊的“订单”字段(例如MySQL中的ORDINAL_POSITION值)。

    因此,您可以 - 提前 - 查询所需表的列的有序列表及其顺序。要查询MySQL,SELECT COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="XXX"。将数据存储在@columns列表中(或者如果您有许多表,数组的散列,%列,表名是键)。

    然后,在构建查询时,您只需说

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

    请注意,发送到服务器的实际 SQL将包含列名,但您不会在代码中的任何位置对这些名称进行硬编码。

答案 1 :(得分:1)

您可以阅读COLUMNS.ORDINAL_POSITION(请参阅here),但这听起来像是等待发生的灾难。

你可以(并且总是应该!)引用``中的列名,例如SELECT `colname`。这将处理表名为ConditionSELECT的情况。

答案 2 :(得分:0)

这里的许多其他人都说过为什么你不想做这样的事情。但是,让我告诉你这到底是多么不可能。

例如,如果您仅知道位置是3的位置,这会告诉您列的名称。

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: Schema Object名称文档:

MySQL中的某些对象,包括数据库,表,索引,列,别名,视图,存储过程,分区,表空间,资源组和其他对象名称,被称为标识符...。

标识符可以带引号或不带引号。如果标识符包含特殊字符或为保留字,则在引用标识符时必须将其引用。

我怀疑您只想要引用的内容。在这种情况下,请使用反引号。同样来自上述来源...

mysql> SELECT * FROM `select` WHERE `select`.id > 100;