【问题标题】:Update row if exists or insert如果存在则更新行或插入
【发布时间】:2020-07-05 03:34:12
【问题描述】:

我正在开发一个基于 Web 的 PHP 表单,该表单当前连接到 Oracle 数据库。我正在尝试使该功能正常工作,以便在用户提交表单后,它将根据作业编号检查是否存在行,如果存在则更新,否则插入值。

目前它返回了一个内部服务器错误,我不太明白为什么。

下面是代码sn-p...

<?php

//connect to database
$DBC = oci_connect("username", "password", "server");

set_time_limit ( 120 );


$jobNumber = $_POST['jobNumber'];

$C1utShortAmount = $_POST['1CutShortAmount'];
$1Scrap = $_POST['1Scrap'];
$1Repair = $_POST['1Repair'];
$1TotalQty = $_POST['1TotalQty'];

$2Scrap = $_POST['2Scrap'];
$2RaisedParts = $_POST['2RaisedParts'];
$2Repair = $_POST['2Repair'];
$2TotalQty = $_POST['2TotalQty'];

$3Repair = $_POST['3Repair'];
$3Scrap = $_POST['3Scrap'];
$3Repair = $_POST['3SmtRepair'];
$3RaisedParts = $_POST['3RaisedParts'];
$3TotalQty = $_POST['3TotalQty'];

$createdBy = $_POST['usersname'];

$sqlSelect = "SELECT * FROM wip.table1 WHERE JOB_NUMBER = '$jobNumber'";

$SQL = "INSERT INTO wip.table1
   ( job_number,
     1_Cut_Short_Amount,
     1_Scrap,
     1_Repair,
     1_Total_Qty,
     2_Scrap,
     2_Raised_Parts,
     2_Repair,
     2_Total_Qty,
     3_Repair,
     3_Scrap,
     3_Repair,
     3_Raised_Parts,
     3_Total_Qty
  )
    VALUES (
      '$jobNumber',
      '$1CutShortAmount',
      '$1Scrap',
      '$1Repair',
      '$1TotalQty',
      '$2Scrap',
      '$2RaisedParts',
      '$2Repair',
      '$2TotalQty',
      '$3Repair',
      '$3Scrap',
      '$3Repair',
      '$3RaisedParts',
      '$3TotalQty'
   )";

   $sql2 = "UPDATE wip.table1
            SET 1CUT_SHORT_AMOUNT = '$1CutShortAmount',
                1SCRAP = '$1Scrap',
                1REPAIR = '$1Repair',
                1TOTAL_QTY = '$1TotalQty',
                2SCRAP = '$2Scrap',
                2RAISED_PARTS = '$2RaisedParts',
                2SMT_REPAIR = '$2Repair',
                2TOTAL_QTY = '$2TotalQty',
                3REPAIR = '$3Repair',
                3SCRAP = '$3eScrap',
                3SMT_REPAIR = '$3SmtRepair',
                3RAISED_PARTS = '$3RaisedParts',
                3TOTAL_QTY = '$3TotalQty'
            WHERE JOB_NUMBER LIKE '$jobNumber'";

   if(oci_num_rows($sqlSelect) > 0){
     $stmt = oci_parse($DBC,$SQL2);

     $rc = oci_execute($stmt);
      if (!$rc)
      {
      $error = oci_error($stmt);
      var_dump($error);
      }

      oci_free_statement($stmt);
   }
   else
   {
     $stmt1 = oci_parse($DBC,$SQL);

     $rc = oci_execute($stmt1);
      if (!$rc)
      {
      $error = oci_error($stmt1);
      var_dump($error);
      }

      oci_free_statement($stmt1);
   }

【问题讨论】:

  • “它现在带回一个内部服务器错误”然后检查您的日志/启用错误报告。
  • $&lt;integer&gt; - 很确定变量不能以整数开头。
  • 警告:您对SQL Injections 持开放态度,应该使用参数化的prepared statements,而不是手动构建查询。

标签: php sql oracle variables sql-insert


【解决方案1】:

Oracle 有MERGE 语法可以一次执行此类更新/插入操作。

这是一个基于表格 3 列的示例:

merge into wip.table1 t              -- target table
using (                              -- source table: pass your parameters here
    select 
        :job_number job_number, 
        :1_cut_short_amount 1_cut_short_amount, 
        :1_scrap 1_scrap 
    from dual
) s
on (s.job_number = t.job_number)      -- define the "match" condition
when matched then                     -- a record already exists: update
    update set 
        t.1_cut_short_amount = s.1_cut_short_amount,
        t.1_scrap = s.1_scrap
when not matched then                 -- no record yet: insert
    insert(job_number, 1_cut_short_amount, 1_scrap)
    values(s.job_number, s.1_cut_short_amount, s.1_scrap)

【讨论】:

  • 如果 OP 不知道接受哪个答案来关闭它。 GMB 的答案应该是接受恕我直言的答案,因为它解决了最重要的问题,即查询。
【解决方案2】:

在 Oracle 中,您需要在 num_rows 之前先解析执行然后获取

<?php

$stmt = oci_parse($DBC,$sqlSelect);

$rc = oci_execute($stmt);
$row=oci_fetch_array($stmt);
$jobExists=oci_num_rows($stmt)>0; 

   if($jobExists){
     $stmt = oci_parse($DBC,$SQL2);

     $rc = oci_execute($stmt);
      if (!$rc)
      {
      $error = oci_error($stmt);
      var_dump($error);
      }

      oci_free_statement($stmt);
   }
   else {
     $stmt1 = oci_parse($DBC,$SQL);
     $rc = oci_execute($stmt1);

      if (!$rc) {

        $error = oci_error($stmt1);
        var_dump($error);

      }

      oci_free_statement($stmt1);
   } 

?>

【讨论】:

  • 谢谢,我刚刚试了一下,效果很好。
【解决方案3】:

除了the answer given by GMB,变量不能以整数开头。

但是,您可以使用 $_1 等,但不能使用 $1 等。

在 PHP.net 上查阅以下变量:

我从手册中引用:

PHP 中的变量由一个美元符号后跟变量名表示。变量名区分大小写。

变量名称遵循与 PHP 中其他标签相同的规则。有效的变量名称以字母或下划线开头,后跟任意数量的字母、数字或下划线。作为正则表达式,它会这样表达:^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

也使用错误报告:

【讨论】:

  • 抱歉,我将变量更改为数字,因为其中包含敏感信息
  • @mat1986 好的。您能否更新您的问题以涵盖此问题?如果你有,我会删除我的答案。
猜你喜欢
  • 1970-01-01
  • 2021-02-04
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多