如果之前不存在则插入新记录,否则更新它。也不要为特定条件插入超过N条记录

时间:2016-05-12 22:30:55

标签: php mysql sql-insert

我创建了以下MySQL表:

CREATE TABLE `tblUsg` (
`id` INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`ip` VARCHAR(46) NOT NULL,
`dtm` DATETIME NOT NULL,
`huid` BINARY(32) NOT NULL,
`licnm` VARCHAR(20) NOT NULL,
`lichld` VARCHAR(256) NOT NULL,
`flgs` INT NOT NULL,
`agnt` VARCHAR(256),

INDEX `ix_huid` (`huid`),
INDEX `ix_licnm` (`licnm`),
UNIQUE KEY `ix_lichuid` (`huid`, `licnm`)
) AUTO_INCREMENT=0 CHARACTER SET utf8 COLLATE utf8_unicode_ci;

然后,以下php脚本的目标是插入新记录,前提是该表中不存在huidlicnm的记录(ix_lichuid唯一密钥限制。)如果是,请改为更新:

if(@mysql_query(
    "INSERT INTO `$tblUsage` (`ip`, `dtm`, `huid`, `licnm`, `lichld`, `flgs`, `agnt`)\n".
    "VALUES ('$strIP', '$strDate', UNHEX('$strHUID'), '$strLicNm', '$strLicHld', '$strFlgs', '$strAgnt')\n".
    "ON DUPLICATE KEY UPDATE `ip`='$strIP', `dtm`='$strDate', `lichld`='$strLicHld', `flgs`='$strFlgs', `agnt`='$strAgnt'"
    , $link) !== false)
{
    //See how many rows did we insert
    $iRows = @mysql_affected_rows($link);

    if($iRows === 1)
    {
        //Added new record
        ...
    }
    else if($iRows === 0 || $iRows === 2)
    {
        //Updated existing record
        ...
    }
    else
    {
        //Error
        ...
    }
}
else
{
    //Error
    ...
}

但现在我需要添加另一个条件 - 使用相同的N插入不超过licnm个记录。 (我指的是表中匹配licnm字段的整体记录。)

知道如何修改上面的SQL来做到这一点吗?我似乎无法弄明白......

PS。我正在使用PHP 5.3

1 个答案:

答案 0 :(得分:0)

您可能想尝试以下方法。这使用PDO而不像@trincot建议的那样。它也有足够的评论让你开始......

    <?php

        // LIKE ONE OF THE MASTERS HERE IN SO JUST COMMENTED, USE PDO INSTEAD OF mysql FUNCTIONS

        // DATABASE CONNECTION CONFIGURATION:
        defined("HOST")     or define("HOST",   "localhost");           //REPLACE WITH YOUR DB-HOST
        defined("DBASE")    or define("DBASE",  "database");            //REPLACE WITH YOUR DB NAME
        defined("USER")     or define("USER",   "root");                //REPLACE WITH YOUR DB-USER
        defined("PASS")     or define("PASS",   "root");                //REPLACE WITH YOUR DB-PASS


        // CREATE A FLAG TO HOLD THE STATUS MESSAGE... WHETHER WE HAVE AN ERROR OR SUCCESS OR WHATEVER:
        $status     = "";

        // CREATE A FUNCTION TO FETCH YOUR DATABASE RESOURCE...
        // THIS WOULD BE BETTER IF ABSTRACTED INTO A SEPARATE FILE OR CLASS
        // AND INCLUDED IN SCRIPTS THAT NEED IT LIKE THIS ONE...
        /**@return PDO */
        function getDBConnectionHandle() {
            try {
                $db = new PDO('mysql:host='.DB_HOST.';dbname='. DB_NAMES,DB_ADMIN,DB_PWORD);
                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                return $db;
            } catch (PDOException $e) {
                // IF THERE WAS AN ANY KIND OF CONNECTION ERROR, "DIE IT OUT" TO THE OUTPUT STREAM:
                die($e->getMessage());
            }
        }


        // OBTAIN A DATABASE CONNECTION HANDLE USING THE "getDBConnectionHandle()" FUNCTION
        $db         = getDBConnectionHandle();

        // SO THE 1ST GOAL HERE IS TO CHECK WHETHER A RECORD WITH A GIVEN "huid" AND "licnm" ALREADY EXISTS IN THE DATABASE TABLE.
        // THAT MEANS WE FIRST RUN A SELECT QUERY TO CHECK IF IT'S THERE OR NOT
        $stmt1      = $db->prepare('SELECT * FROM `' . $tblUsage . '` WHERE huid=:HD AND licnm=:LM');
        $stmt1->bindParam(":HD",    hex2bin($strHUID));
        $stmt1->bindParam(":LM",    $strLicNm);
        $arrResult  = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // NOW CHECK IF THE WE GOT SOMETHING BACK. IF WE DO, WE UPDATE THE TABLE; OTHERWISE WE INSERT A NEW ROW
        if($arrResult && !empty($arrResult)){
            // WE GOT SOMETHING SO WE GO AHEAD AND UPDATE THE TABLE INSTEAD...
            $stmt1  = $db->prepare('UPDATE `' . $tblUsage . '` SET `ip`=:IP,  `dtm`=:DT, `huid`=:HD, `licnm`=:LM, `lichld`=:LD, `flgs`=:FG, `agnt`=:AT WHERE `huid`=:HD2 AND `licnm`=:LM2 ');
            $rData1 = array(
                "IP"    => $strIP,
                "DT"    => $strDate,
                "HD"    => hex2bin($strHUID),
                "LM"    => $strLicNm,
                "LD"    => $strLicHld,
                "FG"    => $strFlgs,
                "AT"    => $strAgnt,
                "HD2"   => hex2bin($strHUID),
                "LM2"   => $strLicNm,
            );

            $isOK   = $stmt1->execute($rData1);
            $status = ($isOK) ? "The Record with licm: {$strLicNm} was successfully updated." : "There was an Error updating the record with licm: {$strLicNm}.";
        }else{
            // WE ARE CLEAR TO PROCEED WITH INSERT: NOTHING CAME BACK!!!
            $stmt2  = $db->prepare('INSERT INTO `' . $tblUsage . '`  (`ip`,  `dtm`, `huid`, `licnm`, `lichld`, `flgs`, `agnt`) VALUES(:IP, :DT, :HD, :LM, :LD, :FG, :AT)');
            $rData2 = array(
                "IP"    => $strIP,
                "DT"    => $strDate,
                "HD"    => hex2bin($strHUID),
                "LM"    => $strLicNm,
                "LD"    => $strLicHld,
                "FG"    => $strFlgs,
                "AT"    => $strAgnt,
            );

            $isOK   = $stmt2->execute($rData2);
            $status = ($isOK) ? "A new Record with was successfully created." : "There was an Error creating new Record.";
        }
        echo $status;