在PHP PDO中如何获取PostgreSQL upsert查询的“RETURNING”子句值

时间:2016-12-10 16:50:11

标签: php postgresql pdo

我有用postgreSQL编写的upsert查询

$stmt = $this->db->prepare($statement);
$returnedId = $stmt->execute(array(
     'CharacterId' => $characterId,
     'LevelId' => $unlockMethod['LevelId'],
     'AmountToBuy' => $unlockMethod['AmountToBuy'],
     'EagleStatueId' => $unlockMethod['EagleStatueId'],
     'Location' => $unlockMethod['Location'],
     'MapCoordinateTop' => $unlockMethod['MapCoordinateTop'],
     'MapCoordinateLeft' => $unlockMethod['MapCoordinateLeft'],
));

查询工作正常,如果我在PgAdmin中运行它,我会按预期返回“CharacterUnlockToBuyLevelId”。但是,如果我准备并使用PHP的PDO执行它,那么我似乎无法获得RETURNING值。

$returnedId

这只返回true,因此public class MyBroadcaseciver extends BroadcastReceiver { MediaPlayer mymedia; @Override public void onReceive(Context context, Intent intent) { mymedia=MediaPlayer.create(context,R.raw.alarm); mymedia.start(); Toast.makeText(context, "Alarm....", Toast.LENGTH_LONG).show(); Intent intent = new Intent(context, Mainscreen.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); sendNotification("title","message", intent, 0); } public void sendNotification(String title, String body, Intent intent,int pushid) { Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(title) .setStyle(new NotificationCompat.BigTextStyle() .bigText(body)) .setContentText(body) .setAutoCancel(true) .setSound(defaultSoundUri); if(intent!=null) { intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT); notificationBuilder.setContentIntent(pendingIntent); } NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0, notificationBuilder.build()); } } 实际上不会保存id,而只是值true。如何使用PDO准备好的语句从upsert查询中获取RETURNING值?

2 个答案:

答案 0 :(得分:1)

来自http://php.net/manual/en/pdostatement.execute.php

  

public bool PDOStatement :: execute([array $ input_parameters])

要返回val,请尝试fetchAll

$stmt = $this->db->prepare($statement);
$returnedId = $stmt->execute(array(
     'CharacterId' => $characterId,
     'LevelId' => $unlockMethod['LevelId'],
     'AmountToBuy' => $unlockMethod['AmountToBuy'],
     'EagleStatueId' => $unlockMethod['EagleStatueId'],
     'Location' => $unlockMethod['Location'],
     'MapCoordinateTop' => $unlockMethod['MapCoordinateTop'],
     'MapCoordinateLeft' => $unlockMethod['MapCoordinateLeft'],
));
$yourVal=$stmt->fetchAll();

答案 1 :(得分:0)

如果您准备扩展PDOStatement课程,可以稍微简化一下这个过程。诀窍是将fetchAll包装在execute方法的扩展版本中。

因为PDOStatement是间接生成的,所以首先需要告诉PDO使用扩展版本,而不是标准版本:

$pdo=new PDO($dsn,$user,$password) or die('oops');
$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement',array($pdo)));

...其中DBStatement将是您的扩展PDOStatement

然后您可以按如下方式扩展该类:

class DBStatement extends PDOStatement {
    public $pdo;
    protected function __construct($pdo) {
        $this->pdo = $pdo;
    }
    function executeReturning($data=null) {
        parent::execute($data);
        return $this->fetchAll();
    }
}

第一部分需要让你的新课程与原版一样开始。第二部分执行语句,然后返回结果。

然后您可以按如下方式调用它:

$sql='INSERT INTO testing(data) VALUES(?) RETURNING id,data';
$pds=$pdo->prepare($sql);
print_r($pds->executeReturning(['this space for rent']));