用户
 找回密码
 入住 CI 中国社区
搜索
查看: 7337|回复: 12
收起左侧

[数据库] CI有预先更新数据的功能?

[复制链接]
发表于 2010-3-2 14:58:37 | 显示全部楼层 |阅读模式
本帖最后由 consatan 于 2010-3-2 15:00 编辑

下面是我的数据库
SQL复制代码
 
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
 
CREATE TABLE IF NOT EXISTS `goods_barcode` (
  `barcode` INT(11) NOT NULL AUTO_INCREMENT COMMENT '条形码',
  `in_id` INT(6) NOT NULL DEFAULT '0' COMMENT '收货单号',
  `out_id` INT(6) NOT NULL DEFAULT '0' COMMENT '发货单号',
  `in_item_no` INT(4) NOT NULL DEFAULT '1' COMMENT '收货组序号',
  `out_item_no` INT(4) NOT NULL DEFAULT '1' COMMENT '发货组序号',
  `status` INT(1) NOT NULL DEFAULT '1' COMMENT '状态(1:就绪|2:收货|3:发货|4:完成)',
  PRIMARY KEY (`barcode`),
  KEY `in_id` (`in_id`),
  KEY `out_id` (`out_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='条形码货物' AUTO_INCREMENT=1011 ;
 
INSERT INTO `goods_barcode` (`barcode`, `in_id`, `out_id`, `in_item_no`, `out_item_no`, `status`) VALUES
(1000, 0, 0, 1, 1, 1),
(1001, 0, 0, 1, 1, 1),
(1002, 0, 0, 1, 1, 1),
(1003, 0, 0, 1, 1, 1),
(1004, 0, 0, 1, 1, 1),
(1005, 0, 0, 1, 1, 1),
(1006, 0, 0, 1, 1, 1),
(1007, 0, 0, 1, 1, 1),
(1008, 0, 0, 1, 1, 1),
(1009, 0, 0, 1, 1, 1),
(1010, 0, 0, 1, 1, 1),
 
CREATE TABLE IF NOT EXISTS `goods_in` (
  `in_bill_id` INT(6) NOT NULL AUTO_INCREMENT COMMENT '收货单号',
  `in_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收货日期',
  PRIMARY KEY (`in_bill_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='收货单' AUTO_INCREMENT=2 ;
 
 
INSERT INTO `goods_in` (`in_bill_id`, `in_date`) VALUES
(0, '2009-01-01 00:00:00');
 
CREATE TABLE IF NOT EXISTS `goods_out` (
  `out_bill_id` INT(6) NOT NULL AUTO_INCREMENT COMMENT '发货单号',
  `out_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发货日期',
  PRIMARY KEY (`out_bill_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='发货单' AUTO_INCREMENT=2 ;
 
INSERT INTO `goods_out` (`out_bill_id`, `out_date`) VALUES
(0, '2009-02-01 00:00:00');
 
ALTER TABLE `goods_barcode`
  ADD CONSTRAINT `goods_barcode_ibfk_2` FOREIGN KEY (`in_id`) REFERENCES `goods_in` (`in_bill_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `goods_barcode_ibfk_3` FOREIGN KEY (`out_id`) REFERENCES `goods_out` (`out_bill_id`) ON DELETE CASCADE ON UPDATE CASCADE;
 
复制代码


下面是Controller
PHP复制代码
 
<?php
  class Goods extends Controller {
    function Goods() {
      parent::Controller();
    }
 
    function barcode() {
      $data = array('info'      => "0",
                    'over'      => 0,
                    'bill_id'   => -1,
                    'item_no'   => 1,
                    'status'    => 0
                    );
      $this->load->view('barcode',$data);
    }
 
    function get_barcode() {
      $action =  $this->input->post('inout');
      $barcode = $this->input->post('barcode');
      $bill_id = $this->input->post('bill_id');
      $item_no = $this->input->post('item_no');
      $status  = $this->input->post('status');
 
      $data = array('info'      => "0",
                    'over'      => 0,
                    'barcode'   => $barcode,
                    'bill_id'   => $bill_id,
                    'item_no'   => $item_no,
                    'status'    => $status
                    );
 
      $this->load->model('Goods_Model','Goods');
      $ise = $this->Goods->isExist($barcode);
      if(count($ise) > 0) {
        $data['status'] = $ise[0]['status'];
        switch ($ise[0]['status']) {
          case 1:
            $this->process_goods($data,$action);
            break;
          case 2:
            if($action == "in_bill") {
              $data = $this->init_data($data);
              $data['info'] = "此条形码的货物已经入库!";
              return $this->load->view('barcode',$data);
            } else if($action == "out_bill") {
              $this->process_goods($data,$action);
            }
            break;
          case 3:
            $data = $this->init_data($data);
            if($action == "out_bill") {
              $data['info'] = "此条形码的货物已经出货!";
            } else if($action == "in_bill") {
              $data['info'] = "此条形码的货物未经入库就已经出货!";
            }
            return $this->load->view('barcode',$data);
            break;
          case 4:
            $data = $this->init_data($data);
            $data['info'] = "此条形码的货物曾经入库,并已经发货!";
            return $this->load->view('barcode',$data);
            break;
        }
      } else {
        $data = $this->init_data($data);
        $data['info'] = "不存在此条形码!";
        return $this->load->view('barcode',$data);
      }
    }
 
    function process_goods($data,$action) {
      $this->load->model('Goods_Model','Goods');
 
      if($data['bill_id'] == -1) {          //bill_id = -1 则建立收货单号
        $bill = $this->Goods->insert_bill($action);
        if($bill != 0) {
          $data['bill_id'] = $bill[0]['liid'];
        }
      }
      $this->Goods->update_bill($data,$action);
      $data['info']     = "0";
      $data['over']     = 2;
      $data['item_no']  = number_format($data['item_no']) + 1;
      $data['status']   = 0;
      $this->load->view('barcode',$data);
    }
 
    function init_data($data) {
      $data['info']    = "0";
      $data['over']    = 0;
      $data['status']  = 0;
      return $data;
    }
  }
?>
 
复制代码

下面是Model
PHP复制代码
 
 
<?php
  class Goods_Model extends Model {
    function Goods_Model() {
      parent::Model();
    }
 
    function isExist($barcode) {
      $sql = "select status from goods_barcode where barcode = ?";
      return $this->db->query($sql,array($barcode))->result_array();
    }
 
    function insert_bill($action) {
      $tab = "";
      $data = array();
      if($action == "in_bill") {
        $tab = "goods_in";
        $data['in_date'] = date('Y-m-d');
      } else {
        $tab = "goods_out";
        $data['out_date'] = date('Y-m-d');
      }
      $this->db->insert($tab,$data);
      return $this->db->query("select last_insert_id() as liid")->result_array();
    }
 
    function update_bill($data,$action) {
      $row = array();
      if($action == "in_bill") {
        $row['id']      = "in_id";
        $row['item_no'] = "in_item_no";
        if($data['status'] == 1) {
          $data['status'] = 2;
        }
      } else if($action == "out_bill") {
        $row['id']      = "out_id";
        $row['item_no'] = "out_item_no";
        if($data['status'] == 2) {
          $data['status'] =4;
        } else if($data['status'] == 1) {
          $data['status'] =3;
        }
      }
      $sql = "UPDATE `goods_barcode` SET `".$row['id']."` = ?, `".$row['item_no']."` = ?, `status` = ? WHERE `barcode` = ?";
      $this->db->query($sql,array($data['bill_id'],$data['item_no'],$data['status'],$data['barcode']));
    }
  }
?>
 
复制代码


最后是View
HTML复制代码
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8" />
    <title>条形码</title>
  </head>
  <body>
    <script type="text/javascript">
      function _submit(obj) {
        document.getElementById('barcode').value = parseInt(document.getElementById('barcode').value,10);
        obj.submit();
      }
    </script>
    <?php
     $URL_SENDBARCODE = array('goods','get_barcode');
   ?>
 
    <form id"sendBC" name="sendBC" method="POST" action="<?php echo site_url($URL_SENDBARCODE) ?>" autocomplete="off" >
     <input type="hidden" id="bill_id" name="bill_id" value="-1" />
     <input type="hidden" id="item_no" name="item_no" value="1" />
     <input type="hidden" id="status" name="status" value="0" />
     <input type="hidden" id="inout" name="inout" value="">
     <div style="text-align:center;">
      <table border="0" style="width:310px;">
        <tr>
          <td>
            <input type="text" id="barcode" name="barcode" value="" maxlength="20" />
          </td>
        </tr>
        <tr>
          <td style="text-align:center;">
            <input type="submit" id="msbc" name="msbc" value="手动提交条形码" />
          </td>
        </tr>
       </table>
      </div>
      <script type="text/javascript">
        document.getElementById('inout').value = "in_bill";
 
        if((parseInt(<?php echo $over ?>,10)) !== 0) {   //$over: 0:默认|1太轻|2:标准|3:过重
          sound((parseInt(<?php echo $over ?>,10)));
        }
 
        if("<?php echo $info ?>" != "0") {
          alert("<?php echo $info ?>");
          document.getElementById('bill_id').value = parseInt(<?php echo $bill_id ?>,10);
          document.getElementById('item_no').value = <?php echo $item_no ?>;
          document.getElementById('status').value = 0;
        }
 
        function sound(num) {
          if(num === 2) {
            alert("入库成功!");
            document.getElementById('bill_id').value = parseInt(<?php echo $bill_id ?>,10);
            document.getElementById('item_no').value = <?php echo $item_no ?>;
            document.getElementById('status').value = 0;
          }
        }
 
        if(document.getElementById('bill_id').value == -1) {
          document.getElementById('bill_id').value = parseInt(<?php echo $bill_id ?>,10);
        }
 
        document.getElementById('barcode').focus();
      </script>
    </form>
  </body>
</html>
 
复制代码


数据库中默认有1000~1010的条形码,我打开http://servername/goods/barcode页面
然后输入1000,提示“入库成功”
然后再输入1001,则有2种可能...一种是入库成功,一种是已经入库...但数据库都是初始化建立的...根本不可能存在已经入库的可能啊(但提示完再去查数据库,状态却确实已经更新为已经入库了...)
今天在弄一个项目的流程...遇到这问题...上面的代码是我把很多其余的信息都删除后,最直接的业务流程了...实在看不出哪里导致我说的这问题...
当局者迷...请路过的帮忙看一下吧...看了3、4个小时了,实在找不出哪里有问题...
 楼主| 发表于 2010-3-2 16:08:44 | 显示全部楼层
我把所有的数据库操作都换成直接写SQL语句(也就3句)
并在执行$this->db->query($sql);之前
echo $sql."<br>";
输出
结果也没看到那些提示已经入库的进行了数据库操作...实在是郁闷...到底是哪里出问题了??
发表于 2010-3-2 16:48:15 | 显示全部楼层
没太看明白 -_-
 楼主| 发表于 2010-3-2 17:19:39 | 显示全部楼层
没太看明白 -_-
Hex 发表于 2010-3-2 16:48

基本上就是前台输入条形码
后台查询是否存在此条形码
存在的话根据条形码的status字段来判断货物是否已经入库
如果status为1,且操作为入库的话
则再判断入库单号是否为-1,是的话则添加入库单,并返回单号
然后再将入库单号更新到条形码对应的数据中,然后将status字段更新为2

现在我初始化了一个数据库,status默认都为1
然后我在前台输入一个条形码,因为status默认都为1,所以应该都是提示入库成功的
但是我输入第2个条形码的时候,却会出现“已经入库”的提示,而我输入的条形码根本就没入库过
但是后台数据库的资料中,第2个条形码确实已经更新为入库状态

我试着把Model中的数据库操作都换成PHP基本的mysql操作,然后用echo进行跟踪,结果也还是没看到那些提示已经入库的数据,到底是在哪里进行了更新操作...
 楼主| 发表于 2010-3-2 17:59:44 | 显示全部楼层
HEX推荐一个简单点的断点调试工具吧....
我想在update语句前添加断点,看看是不是哪里循环调用了...导致执行了update语句后马上又进行查询
 楼主| 发表于 2010-3-2 19:16:36 | 显示全部楼层
看来看去还是看不出我代码中哪里出问题了...
换个方法提问题吧

xxx.JPG


上面的图就是我上面代码的大致流程
本来数据库中的status都默认为1的,也就是说status为2这种情况不可能发生的,除非我故意连续输入2次相同的ID
但现在却随机出现status为2的情况
我就想说是不是我输入ID的时候,程序判断status为1,然后进行更新操作,但却没返回给前台,而是直接又把ID传了回来,然后因为已经更新操作了,所以status为2,提示已经存在?
或者是判断status为1后,进行更新操作,返回到前台,但前台却因为某种原因又自己把ID传回到后台(这样我在更新操作前后加的echo肯定就会被刷新掉)

会不会有我上面说的这种可能啊??
 楼主| 发表于 2010-3-2 19:39:12 | 显示全部楼层
本帖最后由 consatan 于 2010-3-2 19:41 编辑

在update语句前面添加了个写入文件操作,将条形码ID写入到硬盘文件上
发现同一个ID写入2次!!
也就是说同一个ID进行了2次更新操作...
而且连第一次输入,那次我认为100%按照正确流程走的那次,既然也执行了2次update操作...

上面的代码为什么会发生这种情况呢??
 楼主| 发表于 2010-3-2 20:06:21 | 显示全部楼层
……—%%……¥*—…………—
FUXK!!!!!!!!!
刚刚死活不行,终于想到用上面说的写入文件的方法来测试执行流程
没想到....上面说执行2次update是我把数据库操作换成纯MYSQL语句的
然后发现执行2次update后,就换回帖子顶楼帖的代码,没想到...
既然突然就可以了...不会再出现刚才说的情况了...
真的...就上面的代码,完完全全是复制粘帖上去的...
既然就可以了...测试了100多次都没出现上面说的情况了...

我今天一整天都为了这问题想得头都快炸了,既然突然就给我好了...FUXK!!!!
 楼主| 发表于 2010-3-2 20:17:04 | 显示全部楼层
谁能告诉我到底是怎么回事...
难道是双核CPU的问题??
我今天想了一天到底是为谁辛苦为谁忙啊...既然突然间就好了...突然间...
真的是欲哭无泪啊...
 楼主| 发表于 2010-3-2 21:30:25 | 显示全部楼层
0.30744500 1267535227  function barcode()
0.43311900 1267535244  function get_barcode()
0.44776200 1267535244  function get_barcode()
0.50068800 1267535244  function auth_goods()
0.49966900 1267535244  function auth_goods()
0.50083300 1267535244  function get_goods()
0.49981300 1267535244  function get_goods()
0.50495800 1267535244  function get_stand_wgt()
0.50393800 1267535244  function get_stand_wgt()
0.56630600 1267535244  function process_goods()
0.56550000 1267535244  function insert_bill()
0.56652800 1267535244  function insert_bill()
0.62700100 1267535244  function update_bill(96451)
0.62598700 1267535244  function update_bill(96451)
0.40205700 1267535248  function get_barcode()
0.40435100 1267535248  function auth_goods()
0.40444700 1267535248  function get_goods()
0.40494200 1267535248  function get_stand_wgt()
0.40520300 1267535248  function process_goods()
0.40528200 1267535248  function update_bill(96452)
0.41701000 1267535248  function get_barcode()
0.41929300 1267535248  function init_data()
0.41938200 1267535248  已经入库

换回最原始的,有业务逻辑的代码...问题又来了...
上面这个就是最原始代码的执行流程...看看这怪异的执行过程...一个函数连续调用2次!!
而且函数中根本就没有回调的方法...郁闷啊...到底是怎么回事啊...

本版积分规则