1

我有两个文件。一个是从数据库中转储的表创建字符串文件,另一个是表的名称,前缀为“prompt”,后缀为“...”。如下:文件A(索引):

prompt branch...
prompt branch_param...
prompt branch_pre_param...
prompt business...
prompt business_map...
prompt business_type...

文件 B(转储):

CREATE TABLE "KS"."BRANCH"
 ("BRANCH_CODE"       CHARACTER(3)    NOT NULL  DEFAULT '',
  "BRANCH_NAME"       CHARACTER(40)   NOT NULL  DEFAULT '',
  "PARAM_LEVEL"       INTEGER         NOT NULL  DEFAULT 0
 )
  DATA CAPTURE NONE
 IN "LONG_DATA_TBS";


CREATE TABLE "KS"."BRANCH2BANK"
 ("BRANCH_CODE"         CHARACTER(3)    NOT NULL  DEFAULT '',
  "BANK_CODE"           CHARACTER(6)    NOT NULL  DEFAULT '',
  "ACC_COMP_RESULT"     CHARACTER(1)    NOT NULL  DEFAULT ''
 )
  DATA CAPTURE NONE
 IN "SMALL_TBS";

CREATE TABLE "KS"."BRANCH2BOND"
 ("BRANCH_CODE"        CHARACTER(3)    NOT NULL  DEFAULT '',
  "BOND_CODE"          CHARACTER(8)    NOT NULL  DEFAULT '',
  "BOND_NAME"          CHARACTER(20)   NOT NULL  DEFAULT '',
  "TOTAL_AMT"          DECIMAL(19, 4)  NOT NULL  DEFAULT 0,
  "FINANCING_CUST_NO"  CHARACTER(10)   NOT NULL  DEFAULT '',
  "SET_DATE"           CHARACTER(8)    NOT NULL  DEFAULT '',
  "SET_TIME"           CHARACTER(8)    NOT NULL  DEFAULT '',
  "SET_EMP"            CHARACTER(6)    NOT NULL  DEFAULT '',
  "SPARE1"             CHARACTER(20)   NOT NULL  DEFAULT '',
  "SPARE2"             CHARACTER(20)   NOT NULL  DEFAULT ''
 )
  DATA CAPTURE NONE
 IN "SMALL_TBS";

CREATE TABLE "KS"."BRANCH_PARAM"
 ("BRANCH_CODE"    CHARACTER(3)    NOT NULL  DEFAULT '',
  "PARAM_CODE"     CHARACTER(4)    NOT NULL  DEFAULT '',
  "SET_DATE"       CHARACTER(8)    NOT NULL  DEFAULT '',
  "SET_TIME"       CHARACTER(8)    NOT NULL  DEFAULT ''
 )
  DATA CAPTURE NONE
 IN "SMALL_TBS";

CREATE TABLE "KS"."BRANCH_RESERVE_CREDIT_STOCK"
 ("BRANCH_CODE"  CHARACTER(3)    NOT NULL  DEFAULT '',
  "SET_TIME"     CHARACTER(8)    NOT NULL  DEFAULT ''
 )
  DATA CAPTURE NONE
 IN "TX_DATA_TBS"
 INDEX IN "TX_INDEX_TBS";

我已经编写了一个 perl 实现,但我认为它太丑陋且效率低下。有没有更好的方法来改善这一点?

我的代码:(用 Richard 和 lilydjwg 的建议重写)(最新版本)

#!/usr/bin/perl
use 5.016;

my (%hash,$cont);
open IN,'<',shift;
while(<IN>){
    chomp;
    $hash{$1}=1 if /prompt (\w+)\.\.\./;
}
close IN;
open IN,'<',shift;
while(<IN>){
    chomp;
    $cont = (defined $hash{lc $1}?say "prompt $1..." : 0) if /CREATE TABLE "KS"\."(\w+)"/;
    say if $cont == 1;
}
close IN;                   
4

2 回答 2

1

大概是你不喜欢的重复阅读。

所以 - 读取 CREATE TABLE 文件一次,检查:

CREATE TABLE "KS"."(\w+)"

然后,您可以建立表定义,直到下一个 CREATE TABLE,此时您将表定义放入由表名作为键的散列中。

然后,阅读您的提示并从打印出来的哈希中一一获取定义。

或者,您可以将 CREATE TABLE 文件读入单个字符串并搜索+替换表名部分,因为这就是您目前正在更改的所有内容。第一种方法虽然更灵活。


编辑:您可以通过以下方式使定义的内容更加清晰:

while ($line=<IN>) {
    chomp($line);
    if (/CREATE TABLE "KS"\."(\w+)"/ && $hash{lc $1}) {
        $line = ...
    }
    say $line;
}

一旦超出了几行代码,我也喜欢在我的 while 循环中使用显式变量。

于 2012-10-22T09:41:42.870 回答
0

看起来文件A比较小。您可以从中读取并构建一个集合(或类似的),其中包含所有表名。然后读取并识别 SQL 转储文件,对于每个表创建语句,检查该表名是否在您的集合中。

我不太了解 Perl,但这个 Python 代码似乎是你想要的:

import sys

tableNames = {x[7:-3] for l in open(sys.argv[1]) if x.startswith('prompt ')}

for l in open(sys.argv[2]):
  if l.startswith('CREATE TABLE "KS"."'):
    name = l.split('"')[4].lower()
    if name in tableNames:
      print("prompt {0}...\nCreate table{0}(".format(name))
  print(l, end='')
于 2012-10-22T14:29:48.483 回答