0

我在使用一些代码来查找名称的重复项以及平台时遇到了麻烦。这也将适用于稍后查找唯一 ID。

因此,例如,如果 Xbox 上有一个名为“Apple”的服务器,并且您尝试在同一平台上插入一条名为“Apple”的记录,它将拒绝它。但是,允许使用其他同名平台,例如 PS3 中的“Apple”。

我已经尝试过提出想法并寻找答案,但是对于检查重复项的最佳方法是什么我有点摸不着头脑。

到目前为止,这就是我所拥有的:

$nameDuplicate_sql = $db->prepare("SELECT * FROM `servers` WHERE name=':name' AND platform=':platform'");
$nameDuplicate_sql->bindValue(':name', $name);
$nameDuplicate_sql->bindValue(':platform', $platform);
$nameDuplicate_sql->execute();

我尝试了很多不同的解决方案,其中一些来自这里,另一些来自 PHP 手册等。但似乎都没有。

我试图坚持使用 PDO,但是,这是我无法弄清楚转向何处的一个实例。如果这是在 mysql_* 中,我可能只使用 mysql_affected_rows,但对于 PDO,我不知道。rowCount 看起来很有希望,但它总是返回 0,因为这既不是 INSERT、UPDATE 或 DELETE 语句。

哦,我已经在 phpMyAdmin 中尝试过 SQL 语句,它可以工作;我用一个简单的名称/平台尝试了它,它正确地找到了行。

如果有人可以在这里帮助我,我将不胜感激。

4

3 回答 3

2

对于大多数数据库,PDOStatement::rowCount() 不返回受 SELECT 语句影响的行数。相反,使用 PDO::query() 发出 SELECT COUNT(*) 语句,其谓词与预期的 SELECT 语句相同,然后使用 PDOStatement::fetchColumn() 检索将返回的行数。然后,您的应用程序可以执行正确的操作。

于 2012-09-05T02:20:12.330 回答
2

为什么不直接在数据库表上强制执行,而不是检查重复项?创建一个复合键,如果它们已经存在,将禁止进行输入?

CREATE TABLE servers (
    serverName varchar(50),
    platform varchar(50),
    PRIMARY KEY (serverName, platform)
) 

这样,您将永远不会得到重复,并且它还允许您使用 mysqlinsert... on duplicate key update...语法,这听起来对您来说可能相当方便。

如果您已经有一个主键或者您不想创建一个新表,您可以使用以下内容:

ALTER TABLE servers DROP PRIMARY KEY, ADD PRIMARY KEY(serverName, platform);

编辑:主键是单行或必须在其中具有唯一数据的多。单行不能有两次相同的值,但是复合键(这是我在这里建议的)意味着在两列之间,不能出现相同的数据。

在这种情况下,您想要做的是添加服务器名称并将其与平台相关联 - 该表将允许您添加包含相同服务器名称的尽可能多的行 - 只要每个都有一个与相关联的唯一平台它 - 反之亦然,只要所有服务器名称都是唯一的,您就可以根据需要多次列出平台。

如果您尝试在存在相同服务器名称/平台组合的位置插入一条记录,则数据库根本不会让您这样做。不过,还有另一个黄金好处。由于这个键约束 - mysql 允许使用特殊类型的查询。它是insert... on duplicate key update语法。这意味着如果您尝试两次插入相同的数据(即数据库拒绝),您可以捕获它并更新表中已有的行。例如:

您有一行serverName=Fluffeh并且它已打开,platform=Boosh但您现在不知道它,因此您尝试插入一条记录以更新服务器 IP 地址。

通常你会简单地写这样的东西:

insert into servers (serverName, platform, IPAddress) 
values ('$serverName', '$platform', '$IPAddy')

但是如果确定了一个很好的主键,您可以这样做:

insert into servers (serverName, platform, IPAddress) 
values ('$serverName', '$platform', '$IPAddy') 
on duplicate key update set IPAddress='$IPAddy';

如果该行尚不存在,则第二个查询将插入包含所有数据的行。如果确实如此,Bam!它将更新服务器的 IP 地址,这一直是您的意图。

于 2012-09-05T02:21:24.857 回答
1

从参数标记的查询中删除单引号......一旦绑定它们就会被引用......这是准备好的语句的部分原因。

$nameDuplicate_sql = $db->prepare("SELECT * FROM `servers` WHERE name= :name AND platform= :platform");
于 2012-09-05T02:19:27.837 回答