php - 我正在尝试通过 ODBC 将 Sage Line 50 Access 数据库与 Mysql 同步

标签 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 数据库中的每个新表实现 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文件以外的数据。

最佳答案

我知道这有点晚了,但我已经在用 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

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

关于php - 我正在尝试通过 ODBC 将 Sage Line 50 Access 数据库与 Mysql 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22038119/

相关文章:

PHP MySQL 转储命令

php - 在 CodeIgniter 中将参数传递给 index()

mysql - Windows 8.1安装RMySQL的另一个错误

mysql - 是否创建新的数据库连接?

android - 使用 ActiveAndroid 库存储 HashMap<String, Object>

数据库设计问题

database - 如何在 MongoDB 上进行旋转?

php - 有没有办法检测浏览器是否支持 CSS3 动画?

php - CodeIgniter 基本 Controller 扩展

mysql - 无法将 2009-03-08 插入时间戳字段