【发布时间】:2014-06-30 18:09:02
【问题描述】:
我有一个函数调用另一个函数将一些值写入 MSSQL 数据库。如果这些值包含在变量中并且不能在查询中显式写入,则它将字符串请求作为第一个参数和一个包含要在查询中输入的值的数组(查询中有 ?)。这是有问题的功能:
public function dbInsert(){
$curr_date = date('Y-m-d H:i:s');
$this->db->query("INSERT INTO DAI_REQ.META_REQUEST ".
"(DATE_RECU, DATE_TERMINEE, USER_ID, STATUS) ".
"VALUES(?, '', ?, 'R');", array($curr_date, $this->userId));
$mr_select = $this->db->query("SELECT TOP 1 ID FROM DAI_REQ.META_REQUEST WHERE USER_ID = ? ORDER BY ID DESC;",
array($this->userId));
$mr_result = $mr_select->result_array();
$mr_id = $mr_result[0]['ID'];
$sim = 'N/A';
if(isset($this->recurrenceType))
$sim = 'Recurrent';
$this->db->query("INSERT INTO DAI_REQ.REQUEST ".
"(USER_ID, ASSIGNED_DATE, REQUEST_END_DATE, MODEL, EXPERIMENT, VARIABLE, START_DATE, END_DATE, ".
"LON_FROM, LAT_FROM, LON_TO, LAT_TO, RESOLUTION, FORMAT, SIMULATION, STATUS, ".
"CANCELLED_YN, PROJECT, MR_ID, URL_ORIGIN, DATE_EMAIL) ".
"VALUES(?, ?, '', ?, 'N/A', 'N/A', ?, ?, ?, ?, ?, ?, ?, ?, ?, 'R', 0, 'N/A', ?, ?, ?);",
array($this->userId, $curr_date, $this->model, $this->startDate, $this->endDate,
$this->lonFrom, $this->latFrom, $this->lonTo, $this->latTo,
$this->resolution, $this->format, $sim, $mr_id, $this->url_origin, $this->date_email));
$r_select = $this->db->query("SELECT TOP 1 ID FROM DAI_REQ.REQUEST WHERE USER_ID = ? ORDER BY ID DESC;",
array($this->userId));
$r_result = $r_select->result_array();
$this->id = $r_result[0]['ID'];
}
如您所见,我两次调用query 函数,在这两个查询中我使用包含今天日期的变量$curr_date。不幸的是,当我在运行此代码后使用 sql-server 查看数据库时,我在DAI_REQ.META_REQUEST 表中看到的日期与DAI_REQ.REQUEST 表中的日期不同。后者包含好的日期,而前者包含一个随机日期(尽管我每天尝试的日期都相似)。例如,后者为2014-06-30 14:08:40.427,前者为2014-02-19 00:00:00.000
我还必须提到,我们有两台服务器(所以也有两个数据库),一台用于开发,一台用于公共部署。我描述的问题发生在公共部署服务器上,而不是开发服务器上。
我还尝试通过在query 函数中直接调用getdate() 函数来删除$curr_date 变量的使用,如下所示:
$this->db->query("INSERT INTO DAI_REQ.META_REQUEST ".
"(DATE_RECU, DATE_TERMINEE, USER_ID, STATUS) ".
"VALUES(GETDATE(), '', ?, 'R');", array($this->userId));
...
$this->db->query("INSERT INTO DAI_REQ.REQUEST ".
"(USER_ID, ASSIGNED_DATE, REQUEST_END_DATE, MODEL, EXPERIMENT, VARIABLE, START_DATE, END_DATE, ".
"LON_FROM, LAT_FROM, LON_TO, LAT_TO, RESOLUTION, FORMAT, SIMULATION, STATUS, ".
"CANCELLED_YN, PROJECT, MR_ID, URL_ORIGIN, DATE_EMAIL) ".
"VALUES(?, GETDATE(), '', ?, 'N/A', 'N/A', ?, ?, ?, ?, ?, ?, ?, ?, ?, 'R', 0, 'N/A', ?, ?, ?);",
array($this->userId, $this->model, $this->startDate, $this->endDate,
$this->lonFrom, $this->latFrom, $this->lonTo, $this->latTo,
$this->resolution, $this->format, $sim, $mr_id, $this->url_origin, $this->date_email));
什么可能导致这种行为?
【问题讨论】:
-
您可以发布架构吗?这两个表的数据类型可能不同。
-
@BA_Webimax 我现在手头没有架构,但我可以确认
DAI_REQ.REQUEST和DAI_REQ.META_REQUEST中的两个字段都属于(datetime, not null)类型 -
您的代码自然会受到竞争条件的影响。您只是假设在您执行插入和选择之间,不可能将某些其他记录插入到同一用户的数据库中。这是一个BAD假设。您应该使用 @@IDENTITY 或类似的方法来获取您刚刚插入的记录的 id。
-
@MarcB SCOPE_IDENTITY() 更好,但无论哪种情况,它都必须属于同一批次(当前代码发送两个不同的批次)。
-
@MarcB @AaronBertrand 因此,与其写
$mr_select = $this->db->query("SELECT TOP 1 ID FROM AI_REQ.META_REQUEST WHERE USER_ID = ? ORDER BY ID DESC;", array($this->userId));并从该查询中获取ID,不如直接写$mr_id = $this->db->query("SELECT IDENT_CURRENT('DAI_REQ.META_REQUEST');");?
标签: php sql-server date datetime web