我正在将PHP PDO与t-sql(sql server 2017)一起使用。
表结构为
id | ip | datetime
这是代码。
$query ="MERGE INTO ". $this->table_name ." WITH (HOLDLOCK) AS target
USING (SELECT ip=:ip , [datetime]=:datetime ) AS source
ON target.ip = source.ip
WHEN MATCHED
THEN UPDATE
SET [datetime] = :datetime
WHEN NOT MATCHED
THEN INSERT (ip, [datetime])
VALUES (:ip, :datetime);";
// prepare query
$stmt = $this->conn->prepare($query);
// sanitize
$this->datetime=date('Y-m-d H:i:s');
$this->ip=htmlspecialchars(strip_tags($this->ip));
// bind values
$stmt->bindParam(":datetime", $this->datetime);
$stmt->bindParam(":ip", $this->ip);
// execute query
if($stmt->execute()){
return true;
}
return false;
当我使用sql profiler 2017时,我可以看到它执行的查询是
MERGE INTO online WITH (HOLDLOCK) AS target
USING (SELECT ip='10.28.1.67' , [datetime]='2019-01-16 16:32:07' ) AS source
ON target.ip = source.ip
WHEN MATCHED
THEN UPDATE
SET [datetime] = '2019-01-16 16:32:07'
WHEN NOT MATCHED
THEN INSERT (ip, [datetime])
VALUES ('10.28.1.67', '2019-01-16 16:32:07');
当我自己在Sql Server Management Studio 2017中执行此脚本时,它会成功执行(匹配时和不匹配时)。
但是方法$stmt->execute()
返回false
,并且它不会更改表。而且我知道,如果查询不成功,$stmt->execute()
将返回false
。
可能是什么问题?
编辑:现在我收到“ 07002”错误代码,表示“调用参数列表或控制块无效。”。 我将代码更改为
$query ="MERGE INTO ". $this->table_name ." WITH (HOLDLOCK) AS target
USING (SELECT ip='". $this->ip."' , [datetime]='". $this->datetime."' ) AS source
ON target.ip = source.ip
WHEN MATCHED
THEN UPDATE
SET [datetime] = '". $this->datetime."'
WHEN NOT MATCHED
THEN INSERT (ip, [datetime])
VALUES ('". $this->ip."', '". $this->datetime."');";
$stmt = $this->conn->prepare($query);
这有效。但是,第一个查询有什么问题?我不想使用串联