DB2 根据 php 脚本中的绑定参数选择和插入

Posted

技术标签:

【中文标题】DB2 根据 php 脚本中的绑定参数选择和插入【英文标题】:DB2 Select and insert based on bound parameters in php script 【发布时间】:2018-11-05 18:49:27 【问题描述】:

我一直在尝试慢慢迁移一个选择数据的脚本,并根据绑定参数将其插入到另一个表中,从 mysql 到 db2。

我已经迁移了大部分内容,但这个主要部分仍然无法插入。我的选择正在工作,完全符合我的期望。但是,在我创建数组或参数值的地方出了点问题。我只是尝试遍历选定的值行并将值插入到匹配的表中。

我是在错误地使用 odbc_fetch_array,还是我的绑定参数看起来有问题?

//Main query to select data
$data = "
  SELECT  
      u.extension
      , sum(duration) as total_talk_time_seconds
      , round(sum(duration) / 60,2) as total_talk_time_minutes
      , sum(case when legtype1 = 1 then 1 else 0 end) as total_outbound

  from SESSION a
    join call_summary b
      on a.notablecallid = b.notablecallid
    inner join system_USERS u
      on u.EXTENSION = CALLINGPARTYNO or u.EXTENSION = FINALLYCALLEDPARTYNO
  group by extension,u.user_id" or die(db2_conn_error($DB2Conn));


$stmt = "
  INSERT into daily_call_totals
    (extension,
    total_talk_time_seconds,
    total_talk_time_minutes,
    total_outbound)
  VALUES (?, ?, ?, ?)" or die(db2_conn_error($DB2Conn));

//create array for binding
$content = [];

$mainResult = odbc_exec($DB2Conn, $data);
while ($d = odbc_fetch_array($mainResult)) 

  $prepInsert = odbc_prepare($DB2Conn, $stmt);

  //for each row, bind param. This is to ensure we get the correct number of records whether they're being inserted or updated for duplicates
  $values = [
      $d['extension'],
      $d['total_talk_time_seconds'],
      $d['total_talk_time_minutes'],
      $d['total_outbound']];

  // Store the current row
  $content[] = $d;

  if($prepInsert)
      $result = odbc_execute($prepInsert,$values);
      if($result)
        print "successfully added record";
      
    

【问题讨论】:

...这是从 DB2 到 DB2? DB2(就像我知道的每个 RDBMS 一样)允许您使用INSERT <data> FROM SELECT,这更快并且不涉及绑定参数。如果您需要知道插入了哪些行,则需要 FINAL TABLE 功能。但是,如果您需要先执行一些过滤,显然这是行不通的。否则,我们需要更好地了解实际问题是什么。你有错误吗?没结果?您甚至要添加行吗? 所以,我得到了行,但是当它到达插入脚本的部分时,没有抛出任何错误,但是当我从表中选择时,它是空的,表明没有插入任何结果跨度> @Clockwork-Muse 我想我实际上通过执行 INSERT INTO...SELECT 解决了它,但我唯一的挂断是我在两列上有重复的键约束,因为这项工作全天运行但应该每个用户每天只创建一条记录。也许我可以更新它以使用 Merge 那么是的,MERGE 就是答案。 具有 dup 键约束的两列是什么?它们在追加查询中吗? 【参考方案1】:

如前所述,考虑使用INSERT...SELECT 并避免循环使用INSERT...VALUES。事实上,甚至考虑使用 NOT EXISTS 子句避免重复的 ANSI 版本(即,在所有 SQL 支持的 DBMS 中兼容)。但这只会运行 一个 动作,而不是有条件地运行两个动作。

随时都可以运行,并且只会附加 date_of_reportextension 的唯一配对,忽略匹配项。请务必将 date_of_reportmy_report_date_column 替换为实际列,因为您从未在聚合查询中明确这样做。

INSERT into daily_call_totals
        (date_of_report,                                  -- UPDATE COLUMN
         extension,
         total_talk_time_seconds,
         total_talk_time_minutes,
         total_outbound)
SELECT
      my_report_date_column,                              -- UPDATE COLUMN
      u.extension
      , sum(duration) as total_talk_time_seconds
      , round(sum(duration) / 60,2) as total_talk_time_minutes
      , sum(case when legtype1 = 1 then 1 else 0 end) as total_outbound

FROM SESSION a
JOIN call_summary b
  ON a.notablecallid = b.notablecallid
JOIN system_USERS u
  ON u.EXTENSION = CALLINGPARTYNO or u.EXTENSION = FINALLYCALLEDPARTYNO
WHERE NOT EXISTS
   (SELECT sub.date_of_report, sub.extension
    FROM daily_call_totals sub
    WHERE sub.date_of_report = my_report_date_column     -- UPDATE COLUMN
      AND sub.extension = u.extension)
GROUP BY my_report_date_column, extension, u.user_id     -- UPDATE COLUMN 

现在,如果您想有条件地运行两个操作:1) 更新现有值或 2) 插入新值,然后使用 DB2 的 MERGE(在某些但不是所有 RDBMS 中可用):

MERGE INTO daily_call_totals AS d
USING
   (SELECT
          my_report_date_column,                              -- UPDATE COLUMN
          u.extension
          , sum(duration) as total_talk_time_seconds
          , round(sum(duration) / 60,2) as total_talk_time_minutes
          , sum(case when legtype1 = 1 then 1 else 0 end) as total_outbound

    FROM SESSION a
    JOIN call_summary b
      ON a.notablecallid = b.notablecallid
    JOIN system_USERS u
      ON u.EXTENSION = CALLINGPARTYNO or u.EXTENSION = FINALLYCALLEDPARTYNO
    GROUP BY my_report_date_column, extension, u.user_id     -- UPDATE COLUMN
   ) AS q
ON (d.date_of_report = q.my_report_date_column               -- UPDATE COLUMN
    AND d.extension = q.extension)
WHEN MATCHED THEN
     UPDATE SET d.total_talk_time_seconds = q.total_talk_time_seconds,
                d.total_talk_time_minutes = q.total_talk_time_minutes,
                d.total_outbound = q.total_outbound            
WHEN NOT MATCHED THEN
     INSERT (date_of_report,                                 -- UPDATE COLUMN
             extension,
             total_talk_time_seconds,
             total_talk_time_minutes,
             total_outbound)
     VALUES (q.my_report_date_column,                        -- UPDATE COLUMN
             q.extension
             q.total_talk_time_seconds
             q.total_talk_time_minutes
             q.total_outbound);

【讨论】:

这是一个完美的用法,就合并而言。现在试试这个 很高兴听到!很高兴能提供帮助。

以上是关于DB2 根据 php 脚本中的绑定参数选择和插入的主要内容,如果未能解决你的问题,请参考以下文章

PDO从先前选择插入的绑定参数

shell脚本入参包含感叹号怎么处理

如何根据单独列中的月份和年份参数对 DB2 结果进行排序

在 php 中打印来自 db2 查询的单个结果

在 DB2 中进行合并时值不兼容

Db2 for i - RUNSQLSTM - 插入包含数百万条记录的脚本