[英]How can I extract field names from SQL with Perl?
我在文本文件中有一系列選擇語句,我需要從每個選擇查詢中提取字段名稱。 如果某些字段不使用諸如to_char()
等嵌套函數,這將很容易。
給定的select語句字段可能具有多個嵌套括號,例如:
ltrim(rtrim(to_char(base_field_name, format))) renamed_field_name,
還是僅以base_field_name
作為字段的簡單情況,正則表達式在Perl中會是什么樣?
不要嘗試編寫正則表達式解析器(盡管perl正則表達式可以處理類似的嵌套模式),請使用SQL :: Statement :: Structure 。
為什么不問目標數據庫本身如何解釋查詢呢?
在perl中,可以使用DBI查詢准備好的SQL查詢表示形式。 有時這是特定於數據庫的:某些驅動程序(在perl DBD::
名稱空間下)支持RDBMS的描述語句的思想,類似於RDBMS的本機C或C ++ API。
但是,由於DBI會將結果列的名稱放在語句句柄屬性NAME
,因此可以一般地完成。 例如,以下代碼很有可能在任何DBI支持的RDBMS上工作:
use strict;
use warnings;
use DBI;
use constant DSN => 'dbi:YouHaveNotToldUs:dbname=we_do_not_know';
my $dbh = DBI->connect(DSN, ..., { RaiseError => 1 });
my $sth;
while (<>) {
next unless /^SELECT/i; # SELECTs only, assume whole query on one line
chomp;
my $sql = /\bWHERE\b/i ? "$_ AND 1=0" : "$_ WHERE 1=0"; # XXX ugly!
eval {
$sth = $dbh->prepare($sql); # some drivers don't know column names
$sth->execute(); # until after a successful execute()
};
print $@, next if $@; # oops, problem with that one
print join(', ', @{$sth->{NAME}}), "\n";
}
XXX丑陋! 有點嘗試將始終為false的條件附加到SELECT上,以便當您execute()
時,SQL引擎不必執行任何實際工作。 這是一種非常幼稚的方法- /\\bWHERE\\b/i
測試無法正確地識別出SQL WHERE子句,而不是簡單的正則表達式可以正確地解析出SELECT字段名稱-但它可能會起作用。
在辦公室中一個有點相關的問題中,我使用了:
my @SqlKeyWordList = qw/select from where .../; # (1)
my @Candidates =split(/\s/,$SqlSelectQuery); # (2)
my %FieldHash; # (3)
for my $Word (@Candidates) {
next if grep($word,@SqlKeyWordList);
$FieldHash($Word)++;
}
評論:
my @Candidates=split(/[\s \( \) \+ \, \* \/ \- \n \ \= \r ]+/,$SqlSelectQuery );
如何將每行分割成多個字詞(用換行符替換每個括號,逗號和空格),然后進行排序:
perl -ne's/[(), ]/\n/g; print' < textfile | sort -u
您最終將獲得很多內容,例如:
fieldname1 fieldname1 formatstring ltrim rtrim t_char
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.