2

I have a simple table, two columns and one primary key. Here's the PHP I use to populate the table:

$query = "INSERT INTO alt_upcs (sku, upc) VALUES (".$upc[0].",\"".$upc[1]."\")";
mysqli_query($link, $query);
if ($error = mysqli_error($link))
{
  if (preg_match("+DUPLICATE+i", $error))
  {
    $errQuery = "SELECT * FROM alt_upcs WHERE upc LIKE ".$upc[1];
    $result = mysqli_query($link, $errQuery);
    $errRow = mysqli_fetch_row($result);
    echo "Duplicate UPC found: ".$upc[1]." exists for skus ".$errRow[0]." and ".$upc[0].".\n";
  }
  else
  {
    echo $error."\n$query\n";
  }
}

The $upc array is created from an input file containing lines that start with a sku followed by up to 7 upcs. In some rare cases there are more than one sku with the same UPC and in even rarer cases a single sku can have the same UPC twice. The code above works fine for the former, I get the error message Duplicate UPC found: xxxx exists for skus yyyy and zzzz.

But, when there is a sku with two UPCs, and the above block of code runs for the second UPC, I get Duplicate UPC found: xxxx exists for skus and zzzz.

Obviously, MySQL recognizes the duplicate, so why does the error query not show it?

Some additional info, upc is my unique key (primary index) and I can query the table manually and see the value I am attempting to get in my script

Thanks to Bogdan for leading me to my error: I was using LIKE because the field type (which I neglected to share) is varchar and I didn't encapsulate the string $upc[1] insite of double quotes - MySQL thinks I was sending it an int because the string is numeric , which chops off any leading zeros.

Either of these work, but the second is what I should be doing.

  $errQuery = "SELECT * FROM alt_upcs WHERE upc = ".$upc[1];

This works because MySQL comparing the integer value of the field with the integer value of `$upc[1]

  $errQuery = "SELECT * FROM alt_upcs WHERE upc LIKE \"".$upc[1]."\"";

Properly enclosing the string is what I meant to do to begin with.

David Wilkins
  • 574
  • 4
  • 19

2 Answers2

2

Your $errQuery is going to be:

SELECT * FROM alt_upcs WHERE upc LIKE foo

This is a syntax error - the value after the LIKE should be quoted:

SELECT * FROM alt_upcs WHERE upc LIKE 'foo'

Although if you're not going to apply any wildcards, you ought to use a direct equality check:

SELECT * FROM alt_upcs WHERE upc='foo'
nobody
  • 19,814
  • 17
  • 56
  • 77
1

First of all i think your doing it all wrong .. and you should post here the sql table to check out what you got in there. if you don't want to have duplicates in mysql you could use a unique field that will help you keep your data unique in the table. and it might be a duplicate of Find duplicate records in MySQL

Onther way of doing ( i'm not sure from where i have this snippet, never used it so far i had another one )

SELECT my_column, COUNT(*) as count
FROM my_table
GROUP BY my_column
HAVING COUNT(*) > 1

Here is a tutorial about this problem Find duplicates example And if you would use google a little Google find mysql duplicates Another i think this one is the most simple way of doing it.

SELECT * FROM table WHERE name = '$somevalue';

And in php you would have something like this

if($result) {
 throw PDOException("Sorry Mate, Can\'t Do This Insert Duplicate Found");
} else { 
 // Let's make a run for it and insert the new data.
}

My example is just for the purpose of the post of course you should do it a little bit more elegant but my way works just fine :D

Example for mysql select like

I have the following products in my table sorry it's not in english but you will get the ideea i hope.

$bex_products = array(
    array( // row #0
        'ProductName' => 'Hartie Copiator A4 Artist ',
    ),
    array( // row #1
        'ProductName' => 'Hartie Copiator A4 Xerox Bussines',
    ),
    array( // row #2
        'ProductName' => 'Hartie Copiator A3 Xerox Bussines',
    ),
    array( // row #3
        'ProductName' => 'Hartie Copiator A3 Maestro',
    ),
    array( // row #4
        'ProductName' => 'Hartie Copiator A3 Artist ',
    ),
    array( // row #5
        'ProductName' => 'Hartie Copiator A3 Maestro',
    ),
    array( // row #6
        'ProductName' => 'Hartie Copiator A3 Xerox Bussines',
    ),
    array( // row #7
        'ProductName' => 'Hartie Copiator A4 Artist ',
    ),
    array( // row #8
        'ProductName' => 'Hartie Copiator A4 Global',
    ),
    array( // row #9
        'ProductName' => 'Hartie Copiator A4 Xerox Bussines',
    ),
    array( // row #10
        'ProductName' => 'Hartie Copiator Color A4, 160 Gr, - Culori Pale',
    ),
    array( // row #11
        'ProductName' => 'Hartie Copiator Color A4, 80 Gr, - Culori Pale',
    ),
);

For that output i used the following SQL:

SELECT ProductName FROM bex_products WHERE ProductName LIKE 'Hartie Copiator%'

As you can see it returned me all the rows containing the string 'Hartie Copiator' not only one row as i think you would expect too, and that would cause a fail in your code logic that will almost always return a false positive if you get more than few entries in your database.

Output None:

For this output i used the following SQL:

SELECT ProductName FROM bex_products WHERE ProductName LIKE BINARY 'Hartie copiator%'

This one will not return a result because i used binary comparasion and 'Hartie Copiator' !== 'Hartie copiator' because i don't have the 'C' i have 'c'

And now if i do for an exact match:

SELECT ProductName FROM bex_products WHERE ProductName LIKE 'Hartie Copiator A4 Artist%'

Will return

$bex_products = array(
    array( // row #0
        'ProductName' => 'Hartie Copiator A4 Artist ',
    ),
    array( // row #1
        'ProductName' => 'Hartie Copiator A4 Artist ',
    ),
);

And as you can see i have a duplicate entry in the mysql for this product ( that's because they were imported from an excel table and who wrote them added twice there but this will be fixed when we finish with adding products and everything)

For the php part an example.

public function UserNameExists($username) {
    $this->database->query('SELECT UserName FROM tbl_users WHERE UserName = :username');
    $this->database->bind(':username', $username);
    if($this->database->single()) {
        return true;
    }

    return false;
}

I'm sorry but i'm not very good at coding so far.. still learning and some people might find this method written in a bad way ( maybe ) but anyway .. for me it works and .. if it works it's ok. if it's a bad aproach please comment. Anyway what i do there. First i'm using prepared statements then i make a select from table users to check if any record exists there that is equal to the username i got from the form that the user submited. i make the biding then i ask for a single result from the database.

The return value of this function on success depends on the fetch type. In all cases, FALSE is returned on failure. That's from the php manual. well now that we know it returns true or false we can check with an if it's true return true; or "global" return false. and then i use like this:

    if($this->userHelper->UserNameExists('JoeDoe') {
        // set error and show it to the user 
    } else { 
       //run code here
    }

I hope this helps you understand the idea with select like and select exact same thing.

Community
  • 1
  • 1
Bogdan
  • 693
  • 7
  • 26
  • I have a unique key, and mysql reports on an attempted duplicate entry, I capture the error as I designed...But after capturing the error I attempt to find the original in the table and nothing is in the result....but only for an entry that was JUST inserted before the duplicate was attempted – David Wilkins Apr 04 '14 at 16:22
  • your code is searching using LIKE if you want to find a duplicate you have to search for the exact match "Jerry has two apples' !== 'Michelle has two apples' which i think the outcome of your query will be. – Bogdan Apr 04 '14 at 16:26
  • THanks, that wasn't the problem but it led me to the problem – David Wilkins Apr 04 '14 at 16:29
  • Another thing you should use prepared statements, and your code won't show that error because you are not checking if a result is returned or not from mysql. i wish i could stay a little longer and chat but i'm at work. – Bogdan Apr 04 '14 at 16:29
  • I didn't say that was your problem, i gave you options how to check for duplicates, and i told you where you error might be and what might help you simplify your code. but as someone else told you it was in the sql and gave you the advice to use like i told you direct match not with like because that will also return posible matches ( that you won't need and they will cause you more trouble in the future when missmatch duplicate appear). – Bogdan Apr 04 '14 at 16:51
  • Also i'm not familiar with this function used only a couple of times but i think you should use it like this : WHERE upc LIKE BINARY 'foo%'. because LIKE is not case sensitive and the '%' will match any num of chars even zero ones. – Bogdan Apr 04 '14 at 16:53
  • Can you explain how using `LIKE` can result in a false-positive? – David Wilkins Apr 04 '14 at 16:53
  • give me few minutes to make an example on a website i'm working now and i used like there for a simple search on two fields from a table. and i will show you two ways of data return from mysql based on the select stmt's. – Bogdan Apr 04 '14 at 16:57
  • Sidenote: This `("Sorry Mate, Can\'t Do This Insert Duplicate Found)` should read as `("Sorry Mate, Can't Do This Insert Duplicate Found")` --- Notice SO's syntax highlighting? – Funk Forty Niner Apr 04 '14 at 17:01
  • Forgot to close it sorry .. :D i work in a print shop and i have to look at the printer too not only at the monitor :D. – Bogdan Apr 04 '14 at 17:07
  • and forgot to say that instead of return true; you can echo there or log errors or anything you wanna do it. in the way that i'm using in my code the file from where to code was taken holds a bunch of methods for different checkings inserts and stuff related to the user system... and i'm only returning true / false from there nothing more. – Bogdan Apr 04 '14 at 17:37