我试图通过ODBC同步Sage Line 50 Access数据库和Mysql

时间:2014-02-26 10:12:18

标签: php mysql database odbc sage-line-50

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

基本上,我正在编写一个工具,以便本地Intranet站点可以显示从sage到普通员工的数据,而无需使用sage登录(库存等级中的订单等)。我遇到了麻烦,因为看起来Sage50数据库是由总傻瓜开发的。此数据库中没有唯一键,或者更确切地说,非常少。结构真是老派,你可以在pastebin HERE上找到结构(这里的位太大了)。您会注意到有一些表有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 db中的每个新表实现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文件之外的数据。

2 个答案:

答案 0 :(得分:1)

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

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

我还试图处理这些表的更新,因此截断并重新创建。同步时间是秒,因此它不是一个糟糕的选择。它可能有点像球疼,但我说是手动设计你的同步表。

正如你正确指出的那样,圣人对被戳不太友好,所以id说不要尝试同步它。

据推测,您需要向用户提供报告,但您不需要这么做。我同步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的组合。

答案 1 :(得分:0)

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

相关问题