代码之家  ›  专栏  ›  技术社区  ›  Benjamin Oakes

如何在Perl中按DBI的顺序获取列名和行数据?

  •  12
  • Benjamin Oakes  · 技术社区  · 14 年前

    我正在使用DBI查询sqlite3数据库。我所拥有的可以工作,但它不会按顺序返回列。例子:

    Query:  select col1, col2, col3, col4 from some_view;
    Output:
    
        col3, col2, col1, col4
        3, 2, 1, 4
        3, 2, 1, 4
        3, 2, 1, 4
        3, 2, 1, 4
        ...
    
    (values and columns are just for illustration)
    

    我知道这是因为我用的是哈希 ,但如果只使用数组,那么如何返回列名?我要做的就是为任何人买这样的东西 任意的 查询:

        col1, col2, col3, col4
        1, 2, 3, 4
        1, 2, 3, 4
        1, 2, 3, 4
        1, 2, 3, 4
        ...
    

    (也就是说,我需要输出的顺序和列名称正确。)

    我是Perl新手,但我真的认为这是个简单的问题。(我以前在Ruby和PHP中做过这样的工作,但在跟踪Perl文档中要查找的内容时遇到了困难。)

    以下是我目前拥有的精简版:

    use Data::Dumper;
    use DBI;
    
    my $database_path = '~/path/to/db.sqlite3';
    
    $database = DBI->connect(
      "dbi:SQLite:dbname=$database_path",
      "",
      "",
      {
        RaiseError => 1,
        AutoCommit => 0,
      }
    ) or die "Couldn't connect to database: " . DBI->errstr;
    
    my $result = $database->prepare('select col1, col2, col3, col4 from some_view;')
        or die "Couldn't prepare query: " . $database->errstr;
    
    $result->execute
        or die "Couldn't execute query: " . $result->errstr;
    
    ########################################################################################### 
    # What goes here to print the fields that I requested in the query?
    # It can be totally arbitrary or '*' -- "col1, col2, col3, col4" is just for illustration.
    # I would expect it to be called something like $result->fields
    ########################################################################################### 
    
    while (my $row = $result->fetchrow_hashref) {
        my $csv = join(',', values %$row);
        print "$csv\n";
    }
    
    $result->finish;
    
    $database->disconnect;
    
    5 回复  |  直到 9 年前
        1
  •  15
  •   cjm    14 年前

    将“what goes here”注释和以下循环替换为:

    my $fields = join(',', @{ $result->{NAME_lc} });
    print "$fields\n";
    
    while (my $row = $result->fetchrow_arrayref) {
        my $csv = join(',', @$row);
        print "$csv\n";
    }
    

    NAME_lc 以小写形式给出字段名。您也可以使用 NAME_uc 大写,或 NAME 对于任何情况,数据库都决定返回它们。

    你也应该使用 Text::CSV Text::CSV_XS 而不是尝试滚动自己的csv文件,但这是另一个问题。

        2
  •  2
  •   Sujith PS    10 年前

    如果要保留顺序,但仍使用哈希按名称引用字段,请使用:

    $dbh->selectall_arrayref($sql,{ Slice => {} } );
    

    这将为您提供一个哈希的有序数组

        3
  •  2
  •   user4293073    10 年前

    在选择之前在数组中定义列名

    理想情况下,你应该有一个列列表 选择 使用dbi,您将使用该数组。

    如果您需要从散列本身获取列名,这将有效,并且您可以对其进行排序,但没有原始列的迹象 SQL选择 顺序(在哈希中):

    my %cols_hash = ("name" => "john", "age" => 2, "color" => "apalachian");
    my $cols_hash_ref = \%cols;  
    
    my @keys = (sort keys %$cols_hash_ref);  
    my @vals;  
    foreach (@keys){ push @vals, $$cols_hash_ref{$_} };  
    

    希望这有帮助。

    当我搜索时,我找到了一种从DBI中获取列名的方法:

    $sth = $dbh->prepare($query) or die "Prepare exceptioin: $DBI::errstr!";  
    $rv = $sth->execute() or die "Execute exception: $DBI::errstr";  
    $res = $sth->fetchall_arrayref();  
    
    # Array reference with cols captions, which were retrived.  
    $col_names_array_ref = $sth->{NAME};          
    

    这应该按原始顺序给你列名,但我还没有测试过。

        4
  •  1
  •   Randal Schwartz    14 年前

    你要求的结果是散列值。哈希本身就是无序的。也许你想要 fetchrow_arrayref 相反。

    事实上,如果你看过 keys %$row ,您也会看到相应的键出现故障。这就是哈希的本质…每个键都与其值成对出现,但键或值的整体排序是为访问而优化的,而不是外部排序。

        5
  •  1
  •   Patrick_870206    9 年前

    我要做的是:

        use Data::Dump qw(dump);
        # get column names in array
        my @column_names_array= $sth->{NAME};  
        # print out column names in pretty format
        print "Field names: \n";
        dump(@column_names_array);