我正在尝试插入到我的表中,但前提是信息不存在。
这有效:
$sql = //"if not exists (select `id` from friends where `id` = :id) " . //ERROR!
"insert into `friends` (`id`, `fb_id`, `name`, `id2`, `fb_id2`, `name2`) " .
"values (:id, :fb_id, :name, :id2, :fb_id2, :name2)";
try
{
$stmt = $this->db->prepare($sql);
if (!$stmt)
{
$errorcode = (string)
$stmt->errorCode();
trigger_error("mysql errorcode : " . $errorcode, E_USER_ERROR);
$data = array( "note" => "mysql error code: " . $errorcode );
return json_encode( $data );
}
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->bindParam(':fb_id', $fb_id, PDO::PARAM_INT);
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':id2', $id2, PDO::PARAM_INT);
$stmt->bindParam(':fb_id2', $fb_id2, PDO::PARAM_INT);
$stmt->bindParam(':name2', $name2, PDO::PARAM_STR);
$result = $stmt->execute();
$stmt->closeCursor();
}
catch (Exception $e)
{
die ($e->getMessage() );
}
我在第一行中尝试了if not exists ( select id ...
等,但这没有用。它使用00000
返回了错误代码(string) $stmt->errorCode();
,我用Google搜索它意味着:to many mysql connections
,这不是问题,因为其他查询工作正常。
如何在不存在时插入表中,如何获取mysql错误信息?
答案 0 :(得分:3)
我之前从未见过你的语法,在insert子句之前放置一个exists子句,但以下内容应该有效。
INSERT INTO `friends`
SELECT :id, :fp_id, :name, :id2, :fb_id2, :name2
FROM `friends`
WHERE NOT EXISTS ( select `id` from friends where `id` = :id )
LIMIT 1;
刚才意识到在此之前你的朋友桌中至少需要一条记录。
答案 1 :(得分:2)
insert IGNORE into `friends` (`id`, `fb_id`, `name`, `id2`, `fb_id2`, `name2`)
values (:id, :fb_id, :name, :id2, :fb_id2, :name2)
或者您想要防止重复的ID,您可以添加触发器
DELIMITER $$
CREATE TRIGGER bi_friends_each BEFORE INSERT ON friends FOR EACH ROW
BEGIN
DECLARE TestId integer;
SELECT id INTO TestId FROM friends WHERE id = new.id LIMIT 1;
IF (id IS NOT NULL) THEN BEGIN
/*force an error to prevent insert*/
SELECT * FROM force_an_error_table_unwilling_to_insert_dup_key;
END; END IF;
END $$
DELIMITER ;
请注意,如果id
是UNIQUE
或PRIMARY KEY
字段,则插入重复密钥会产生错误,会回滚任何待处理的交易。
如果您使用的是非事务引擎,MySQL将停止在错误点插入行,只会插入部分行。
您的问题很清楚,为什么要进行IGNORE
测试。所以我会回顾一下选项和含义:
id
设置为主键并正常插入,生成的冲突将生成错误并回滚事务。 AUTOINCREMENT
,并将id的值替换为null。 INSERT INTO table (id, fb_id,name,id,fb_id2,name2) VALUES (
null
,:fb_id,:name,:id2,:fb_id2,:name2)
INSERT IGNORE ...
进行操作。 SELECT
,并且在测试显示保存后继续进行INSERT a bunch of values
。 答案 2 :(得分:1)
假设您有一个唯一的id索引,您可以使用INSERT IGNORE
。有关优缺点的讨论,请参阅此帖子:"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
答案 3 :(得分:0)
即使您的表中没有任何行,此解决方案仍然有效。
INSERT INTO t (
x,
y,
z) (
SELECT
'00000',
'11111',
'22222'
FROM
DUAL
WHERE
NOT EXISTS (
SELECT
1
FROM
t
WHERE
c = '00000'
AND x = '11111'
AND y = '22222'
)
LIMIT 1
);