我用以下SQL构建了两个表:
CREATE TABLE state(
IDstate INTEGER not null auto_increment,
state_name VARCHAR(40) not null,
UNIQUE(state_name),
CONSTRAINT IDstate PRIMARY KEY(IDstate)
)auto_increment=100;
CREATE TABLE city(
IDcity INTEGER not null auto_increment,
city_name VARCHAR(60) not null,
IDstate INTEGER not null,
CONSTRAINT IDcity PRIMARY KEY(IDcity),
CONSTRAINT IDstate FOREIGN KEY(IDstate) REFERENCES state(IDstate)
)auto_increment=100;
我想用PHP-PDO-MySQL创建一个函数,我确定下一个:
- 我的函数接收两个参数:
$state
,$city
。 我必须避免重复的值。
$dbcon=new PDO('mysql:host=localhost; dbname=hotel','root', ''); $sql = "SELECT IDstate FROM state WHERE state_name=:state_name"; $query = $dbcon->prepare($sql); $query->execute(array(':state_name'=>$state_name)); $array = $query->fetchAll(); if ($query->rowCount() == 0){ $sql = "INSERT INTO state (state_name) VALUES (:state_name);"; $query = $dbcon->prepare($sql); $query->execute(array(':state_name'=>$state_name)); $sql = "INSERT INTO city (city_name, IDstate) VALUES (:city_name, :IDstate);"; $query = $dbcon->prepare($sql); $query->execute(array(':city_name'=>$city_name, ':IDstate'=>$dbcon->lastInsertId())); } else { $IDstate = $array[0]['IDstate']; $sql = "INSERT INTO city (city_name, IDstate) VALUES (:city_name, :IDstate)"; $query = $dbcon->prepare($sql); $query->execute(array(':city_name'=>$city_name, ':IDstate'=>$IDstate)); print_r($query->rowCount()); }
我需要涵盖以下选项:
- 插入新的州和城市。
- 为现有的州插入新的城市。
- 避免同时插入现有州和城市。
上面的代码工作得很好,但我想改进它。我正在阅读关于最好的选择是写一个transaction
而不是以前的代码。
另一方面,我需要添加第三个表,也许是第四个表,我认为我重复了很多代码:样板代码。
我想听听你的意见和建议。Transactions
用于实现原子性、一致性、隔离性和持久性(ACID)。也就是说,要么所有的insert
语句都应该执行,要么如果其中任何一个语句失败,那么所有其他语句都应该回滚。我们启动一个事务,然后继续执行insert
语句,如果在执行所有语句后没有出现技术/业务错误,那么commit
事务否则rollback
。如果回滚,所有的插入语句将被取消,即开始执行transaction
之后。如果这是你想要的,这里有一个链接,可以通过事务执行多个插入。
所以,这可能不能完全回答你的问题,但这是我的想法:
- 如果它工作,不要修复它。 你用的是什么引擎?如果你正在使用MySQL的MyISAM表,它将不支持事务,也不会返回一个错误。
- 根据你期望的音量大小,你的声音不应该太慢。
- 为您的选择添加限制,因为您只获得一个州名。限制有很大的性能提升。
- 美国最长的州名是13个字符,而不是40个