1

我正在尝试从 sage line 50 数据库中获取结构和数据,但我的更新/创建脚本有问题。

基本上,我正在编写一个工具,以便本地 Intranet 站点可以显示从 Sage 到普通员工的数据,而无需使用 Sage 登录(到期订单/库存水平等)。我遇到了麻烦,因为 Sage50 数据库似乎是由白痴开发的。此数据库中没有唯一键,或者更准确地说,非常少。这个结构真的很老派,你可以在这里找到 pastebin 的结构(这里有点太大了)。您会注意到有些表有 300 多列,我认为这有点愚蠢。但是,我必须解决这个问题,所以我需要一个解决方案。

我遇到了一些同步问题。主要是因为 ODBC 不能将语句限制为 1 行,因此我可以检查数据类型,其次,由于没有 ID,我无法在插入时检查它是否重复。目前,这就是我所拥有的:

$rConn = odbc_connect("SageLine50", "user", "password");

if ($rConn == 0) {
    die('Unable to connect to the Sage Line 50 V12 ODBC datasource.');
}

$result = odbc_tables($rConn);

$tables = array();

while (odbc_fetch_row($result)){
    if(odbc_result($result,"TABLE_TYPE")=="TABLE") {
        $tables[odbc_result($result,"TABLE_NAME")] = array();
    }
}

这将生成您在 pastebin 上看到的列表的第一级。

然后运行 ​​foreach 语句以生成具有表中列的下一个级别

foreach($tables as $k=> $v) {
    $query = "SELECT * FROM ".$k;
    $rRes = odbc_exec($rConn,$query);
    $rFields = odbc_num_fields ($rRes);
    $i = 1;
    while($i <= $rFields) {
        $tables[$k][] = odbc_field_name($rRes, $i);
        $i++;   
    }
    CreateTableandRows($k,$tables[$k]);
}

目前,我有一个共同的功能来创建每个表(不是我喜欢它的方式)。

因为我不能自动抢回一行(或几行),所以用 get_type() 检查数据类型然后自动设置行类型,这意味着我能想出的唯一方法就是设置行类型为文本,然后根据 Mysql 查询追溯更改它们。

这是在上述 foreach 之后为创建表而调用的函数。

function CreateTableandRows($table,$rows) {
    $db = array(
        "host" => '10.0.0.200',
        "user" => 'user',
        "pass" => 'password',
        "table" => 'ccl_sagedata'
    );

$DB = new Database($db);

    $LocSQL = "CREATE TABLE IF NOT EXISTS `".$table."` (
            `id` int(11) unsigned NOT NULL auto_increment,
            PRIMARY KEY  (`id`),";  

    foreach($rows as $k=>$v) {
            $LocSQL .= "
            ".$v." TEXT NOT NULL default '',";
    }

    $LocSQL = rtrim($LocSQL, ',');

    $LocSQL .= "
            ) ENGINE=MyISAM  DEFAULT CHARSET=utf8";

    echo '<pre>'.$LocSQL.'</pre>';

    $DB->query($LocSQL);

}

然后我需要/想要一个函数,它一次获取每个表并将数据同步到 ccl_sagedata 数据库。但是,它需要确保它没有插入重复项,即该脚本将在每天的开始或结束时运行以同步 sage 数据库,并且没有 ID 号 INSERT REPLACE 将不起作用。我显然正在为 ccl_sagedata 数据库中的每个新表实现 auto inc 主 ID。但是我需要能够在每个表中引用我可以通过 ODBC 识别的静态内容(我希望这是有道理的)。在我当前的函数中,它必须为 sage 数据库上的每一行调用 mysql 数据库,并查看是否有匹配的行。

function InsertDataFromSage($ODBCTable) {
    $rConn = odbc_connect("SageLine50", "user", "pass");
    $query = "SELECT * FROM ".$ODBCTable;
    $rRes = odbc_exec($rConn,$query);
    $rFields = odbc_num_fields ($rRes);
    while( $row = odbc_fetch_array($rRes) ) {
        $result[] = $row;
    } 
    $DB = new Database($db);
    foreach($result as $k => $v) {
        $CHECKEXISTS = "SELECT * FROM ".$ODBCTable." WHERE";
        $DB->query($CHECKEXISTS);
        // HERE WOULD BE A PART THAT PUTS DATA INTO THE DATABASE IF IT DOESN'T ALREADY EXIST
    }
}

我唯一能想到的另一件事是“新数据库”类只是一个功能化的标准 mysqli 数据库类。这不是我遇到的问题。

所以要重新盖帽。

  1. 我正在尝试创建一个同步脚本,该脚本在 mysql 数据库中创建(如果不存在)表,然后导入/同步数据。
  2. ODBC 无法限制输出,因此我无法自动确定列中的数据类型(不能手动执行,因为它是一个包含 80 多个表的大型数据库
  3. 我不知道如何阻止脚本创建重复项,因为 sage 源数据库中没有 ID。
  4. 对于那些不在英国的人来说,Sage 是一个靠水和煤运行的无用会计软件包。
  5. Sage 数据库只提供数据,它不允许您在实际程序中输入 csv 文件之外的数据。
4

2 回答 2

1

我知道这有点晚了,但我已经在做同样的事情,但使用的是 MS SQL。

我使用了一个 DTS 包,它截断表的已知副本(即AUDIT_JOURNAL),然后每天复制所有内容。

我在尝试处理这些表的更新时也遇到了一些困难,因此需要截断并重新创建。同步时间是秒,所以它不是一个坏选择。这可能有点痛,但我说手动设计你的同步表。

正如您正确指出的那样,圣人对被戳不是很友好,所以我说也不要尝试同步所有内容。

大概您需要向用户展示报告,但您不需要那么多。我同步COMPANY,AUDIT_JOURNAL, AUDIT_USAGE, CAT_TITLE,CAT_TITLE_CUS, CHART_LIST,CHART_LIST_CUS, BANK,CATEGORY,CATEGORY_CUS,DEPARTMENT, NOMINAL_LEDGER,PURCHASE_LEDGER,SALES_LEDGER

这允许重新创建所有主要报告(资产负债表、试算表、供应商余额等都可以向下钻取)。如果您需要更多帮助,请告诉我。我有一个名为 MIS 的 Web 应用程序,您可以在本地安装它,但同步是 ODBC 和 DTS 的组合。

于 2014-11-09T19:18:41.647 回答
0

好的,您不需要创建同步脚本,您可以实时查询 ODBC,您甚至可以像在 SQL 中那样进行连接以从多个表中检索数据。您唯一不能做的就是将数据写回 Sage。

于 2014-02-26T14:25:31.907 回答