将正在运行的Symfony应用程序从MySQL更改为PostgreSQL会导致
SQLSTATE [42601]:语法错误:7错误:语法错误在或附近 “WHERE”第1行:... Id和a4_.functionName ='expiringAlertsAction') 在哪里...
到目前为止,我无法确定发生这种情况的原因。使用MySQL,查询返回预期结果。我的理解是错误发生在WHERE
之前的某个地方,但我的试验改变都没有奏效。
public function expiringOppsSent($sent = true)
{
$nextMonth = date_add(new \DateTime(), new \DateInterval('P1M'));
$expiryMonth = date_format($nextMonth, 'm');
$expiryYear = date_format($nextMonth, 'Y');
$expireDateCriterion = ($sent) ? "a.date IS NOT NULL" : "a.date IS NULL";
$sqlString =
<<<EOT
SELECT op
FROM TruckeeVolunteerBundle:Opportunity op
JOIN TruckeeVolunteerBundle:Organization o
WITH op.organization = o
JOIN TruckeeVolunteerBundle:Staff s WITH s.organization = o
LEFT JOIN TruckeeVolunteerBundle:AdminOutbox a
WITH op.id = a.oppId AND a.functionName = 'expiringAlertsAction'
WHERE SUBSTRING(op.expireDate, 6, 2) = '$expiryMonth' AND
SUBSTRING(op.expireDate, 1, 4) = '$expiryYear' AND
(op.expireDate <> a.date OR
$expireDateCriterion) AND
op.active = 1 AND o.active = 1 ORDER BY o.orgName
EOT;
$sent = $this->getEntityManager()
->createQuery($sqlString)->getResult();
return $sent;
由Doctrine编写的SELECT
o0_.id AS id_0,
o0_.oppName AS oppName_1,
o0_.add_date AS add_date_2,
o0_.lastUpdate AS lastUpdate_3,
o0_.minAge AS minAge_4,
o0_.active AS active_5,
o0_.group_ok AS group_ok_6,
o0_.expireDate AS expireDate_7,
o0_.description AS description_8,
o0_.orgId AS orgId_9
FROM
opportunity o0_
INNER JOIN organization o1_ ON (o0_.orgId = o1_.id)
INNER JOIN staff s2_
INNER JOIN person p3_ ON s2_.id = p3_.id
AND (s2_.orgId = o0_.orgId)
LEFT JOIN admin_outbox a4_ ON (
o0_.id = a4_.oppId
AND a4_.function = 'expiringAlertsAction'
)
WHERE
MONTH(o0_.expireDate) = '09'
AND YEAR(o0_.expireDate) = '2015'
AND (
o0_.expireDate <> a4_.date
OR a4_.date IS NOT NULL
)
AND o0_.active = 1
AND o1_.active = 1
ORDER BY
o1_.orgName ASC
class Opportunity
{
public function __construct()
{
$this->volunteers = new ArrayCollection();
$this->email = new ArrayCollection();
$this->searches = new ArrayCollection();
}
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="oppName", type="string", length=66, nullable=true)
* @Assert\NotBlank(message = "Opportunity name is required")
*/
private $oppName;
/**
* @var \DateTime
*
* @ORM\Column(name="add_date", type="date", nullable=true)
*/
private $addDate;
/**
* @var \DateTime
*
* @ORM\Column(name="lastUpdate", type="datetime", nullable=true)
*/
private $lastupdate;
/**
* @var integer
*
* @ORM\Column(name="minAge", type="integer", nullable=true)
*/
private $minage;
/**
* @var boolean
*
* @ORM\Column(name="active", type="boolean", nullable=true)
*/
private $active;
/**
* @var boolean
*
* @ORM\Column(name="group_ok", type="boolean", nullable=true)
*/
private $groupOk;
/**
* @var \DateTime
*
* @ORM\Column(name="expireDate", type="date", nullable=true)
* @Assert\Date()
*/
private $expireDate;
/**
* @var string
*
* @ORM\Column(name="description", type="text", nullable=true)
* @Assert\NotBlank(message="Description is required")
*/
private $description;
/**
* @var \Truckee\VolunteerBundle\Entity\Organization
*
* @ORM\ManyToOne(targetEntity="Truckee\VolunteerBundle\Entity\Organization", inversedBy="opportunities", cascade={"persist","remove"})
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="orgId", referencedColumnName="id")
* })
*/
private $organization;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Truckee\VolunteerBundle\Entity\Search", mappedBy="opportunity", cascade={"persist","remove","merge"})
*/
protected $searches;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Opportunity
*/
public function setOppName($name)
{
$this->oppName = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getOppName()
{
return $this->oppName;
}
/**
* Set addDate
*
* @param \DateTime $addDate
* @return Opportunity
*/
public function setAddDate($addDate)
{
$this->addDate = $addDate;
return $this;
}
/**
* Get addDate
*
* @return \DateTime
*/
public function getAddDate()
{
return $this->addDate;
}
/**
* Set lastupdate
*
* @param \DateTime $lastupdate
* @return Opportunity
*/
public function setLastupdate($lastupdate)
{
$this->lastupdate = $lastupdate;
return $this;
}
/**
* Get lastupdate
*
* @return \DateTime
*/
public function getLastupdate()
{
return $this->lastupdate;
}
/**
* Set minage
*
* @param integer $minage
* @return Opportunity
*/
public function setMinage($minage)
{
$this->minage = $minage;
return $this;
}
/**
* Get minage
*
* @return integer
*/
public function getMinage()
{
return $this->minage;
}
/**
* Set active
*
* @param boolean $active
* @return Opportunity
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
/**
* Get active
*
* @return boolean
*/
public function getActive()
{
return $this->active;
}
/**
* Set group
*
* @param boolean $groupOk
* @return Opportunity
*/
public function setGroupOk($groupOk)
{
$this->groupOk = $groupOk;
return $this;
}
/**
* Get group
*
* @return boolean
*/
public function getGroupOk()
{
return $this->groupOk;
}
/**
* Set expiredate
*
* @param \DateTime $expiredate
* @return Opportunity
*/
public function setExpireDate($expiredate)
{
$this->expireDate = $expiredate;
return $this;
}
/**
* Get expiredate
*
* @return \DateTime
*/
public function getExpireDate()
{
return $this->expireDate;
}
/**
* Set description
*
* @param string $description
* @return Opportunity
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set organization
*
* @param \Truckee\VolunteerBundle\Entity\Organization $organization
* @return Opportunity
*/
public function setOrganization(\Truckee\VolunteerBundle\Entity\Organization $organization = null)
{
$this->organization = $organization;
return $this;
}
/**
* Get organization
*
* @return \Truckee\VolunteerBundle\Entity\Organization
*/
public function getOrganization()
{
return $this->organization;
}
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Skill", inversedBy="opportunities", cascade={"persist"})
* @ORM\JoinTable(name="opp_skill",
* joinColumns={@ORM\JoinColumn(name="oppId", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="skillId", referencedColumnName="id")}
* ))
* @Assert\NotNull(message="Please select at least one")
*/
protected $skills;
/**
* Add skills
*
* @param \Truckee\VolunteerBundle\Entity\Skill $skills
* @return Opportunity
*/
public function addSkill(\Truckee\VolunteerBundle\Entity\Skill $skill)
{
$this->skills[] = $skill;
return $this;
}
/**
* Remove skills
*
* @param \Truckee\VolunteerBundle\Entity\Skill $skills
*/
public function removeSkill(\Truckee\VolunteerBundle\Entity\Skill $skill)
{
$this->skills->removeElement($skill);
}
/**
* Get skills
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getSkills()
{
return $this->skills;
}
/**
* Get search
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getSearches()
{
return $this->searches;
}
}
class Organization
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="orgName", type="string", length=65, nullable=true)
* @Assert\NotBlank(message="Organization name is required")
*/
protected $orgName;
/**
* @var string
*
* @ORM\Column(name="address", type="string", length=50, nullable=true)
*/
protected $address;
/**
* @var string
*
* @ORM\Column(name="city", type="string", length=50, nullable=true)
*/
protected $city;
/**
* @var string
*
* @ORM\Column(name="state", type="string", length=50, nullable=true)
*/
protected $state;
/**
* @var string
*
* @ORM\Column(name="zip", type="string", length=10, nullable=true)
*/
protected $zip;
/**
* @var string
*
* @ORM\Column(name="phone", type="string", length=50, nullable=true)
* @V2Assert\PhoneNumber
*/
protected $phone;
/**
* @var string
*
* @ORM\Column(name="website", type="string", length=50, nullable=true)
*/
protected $website;
/**
* @var boolean
*
* @ORM\Column(name="active", type="boolean", nullable=true)
*/
protected $active;
/**
* @var boolean
*
* @ORM\Column(name="temp", type="boolean", nullable=false)
*/
protected $temp;
/**
* @var \DateTime
*
* @ORM\Column(name="add_date", type="datetime", nullable=true)
*/
protected $addDate;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Truckee\VolunteerBundle\Entity\Opportunity", mappedBy="organization", cascade={"persist","remove"})
*/
protected $opportunities;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Truckee\VolunteerBundle\Entity\Search", mappedBy="organization", cascade={"persist","remove","merge"})
*/
protected $searches;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Truckee\VolunteerBundle\Entity\Staff", mappedBy="organization", cascade={"persist","remove","merge"})
*/
protected $staff;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Focus", inversedBy="organizations", cascade={"persist"})
* @ORM\JoinTable(name="org_focus",
* joinColumns={@ORM\JoinColumn(name="orgId", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="focusId", referencedColumnName="id")}
* ))
* @Assert\NotNull(message="Please select at least one")
*/
protected $focuses;
/**
* @ORM\Column(name="background", type="boolean", nullable=true)
*/
protected $background;
/**
* Constructor
*/
public function __construct()
{
$this->opportunities = new ArrayCollection();
$this->staff = new ArrayCollection();
$this->searches = new ArrayCollection();
$this->focuses = new ArrayCollection();
$this->active = true;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set organization
*
* @param string $organization
* @return Organization
*/
public function setOrgName($name)
{
$this->orgName = $name;
return $this;
}
/**
* Get organization
*
* @return string
*/
public function getOrgName()
{
return $this->orgName;
}
/**
* Set address
*
* @param string $address
* @return Organization
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* @return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Set city
*
* @param string $city
* @return Organization
*/
public function setCity($city)
{
$this->city = $city;
return $this;
}
/**
* Get city
*
* @return string
*/
public function getCity()
{
return $this->city;
}
/**
* Set state
*
* @param string $state
* @return Organization
*/
public function setState($state)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* @return string
*/
public function getState()
{
return $this->state;
}
/**
* Set zip
*
* @param string $zip
* @return Organization
*/
public function setZip($zip)
{
$this->zip = $zip;
return $this;
}
/**
* Get zip
*
* @return string
*/
public function getZip()
{
return $this->zip;
}
/**
* Set phone
*
* @param string $phone
* @return Organization
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* @return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set website
*
* @param string $website
* @return Organization
*/
public function setWebsite($website)
{
$this->website = $website;
return $this;
}
/**
* Get website
*
* @return string
*/
public function getWebsite()
{
return $this->website;
}
/**
* Set active
*
* @param boolean $active
* @return Organization
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
/**
* Get active
*
* @return boolean
*/
public function getActive()
{
return $this->active;
}
/**
* Set temp
*
* @param boolean $temp
* @return Organization
*/
public function setTemp($temp)
{
$this->temp = $temp;
}
/**
* Get temp
*
* @return boolean
*/
public function getTemp()
{
return $this->temp;
}
/**
* Set addDate
*
* @param \DateTime $addDate
* @return Organization
*/
public function setAddDate($addDate)
{
$this->addDate = $addDate;
return $this;
}
/**
* Get addDate
*
* @return \DateTime
*/
public function getAddDate()
{
return $this->addDate;
}
/**
* Add opportunities
*
* @param \Truckee\VolunteerBundle\Entity\Opportunity $opportunities
* @return Organization
*/
public function addOpportunity(\Truckee\VolunteerBundle\Entity\Opportunity $opportunity)
{
$this->opportunities[] = $opportunity;
return $this;
}
/**
* Remove opportunities
*
* @param \Truckee\VolunteerBundle\Entity\Opportunity $opportunities
*/
public function removeOpportunity(\Truckee\VolunteerBundle\Entity\Opportunity $opportunity)
{
$this->opportunities->removeElement($opportunity);
}
/**
* Get opportunities
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getOpportunities()
{
return $this->opportunities;
}
// /**
// * Add staff
// *
// * @param \Truckee\VolunteerBundle\Entity\Staff $staff
// * @return Organization
// */
// public function addStaff(\Truckee\VolunteerBundle\Entity\Staff $staff)
// {
// echo "We found it!";die;
// $this->staff[] = $staff;
//
// return $this;
// }
// /**
// * Remove staff
// *
// * @param \Truckee\VolunteerBundle\Entity\Staff $staff
// */
// public function removeStaff(\Truckee\VolunteerBundle\Entity\Staff $staff)
// {
// $this->staff->removeElement($staff);
// }
/**
* Get staff
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getStaff()
{
return $this->staff;
}
/**
* Add search
*
* @param \Truckee\VolunteerBundle\Entity\Search $search
* @return Organization
*/
public function addSearch(\Truckee\VolunteerBundle\Entity\Search $search)
{
$this->searches[] = $search;
return $this;
}
/**
* Remove search
*
* @param \Truckee\VolunteerBundle\Entity\Search $search
*/
public function removeSearch(\Truckee\VolunteerBundle\Entity\Search $search)
{
$this->searches->removeElement($search);
}
/**
* Get search
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getSearch()
{
return $this->search;
}
/**
* Add focuses
*
* @param \Truckee\VolunteerBundle\Entity\Focus $focuses
* @return Organization
*/
public function addFocus(\Truckee\VolunteerBundle\Entity\Focus $focus)
{
$this->focuses[] = $focus;
return $this;
}
/**
* Remove focuses
*
* @param \Truckee\VolunteerBundle\Entity\Focus $focuses
*/
public function removeFocus(\Truckee\VolunteerBundle\Entity\Focus $focus)
{
$this->focuses->removeElement($focus);
}
/**
* Get focuses
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getFocuses()
{
return $this->focuses;
}
/**
* @var boolean
*
* @ORM\Column(name="email", type="string", nullable=true)
*/
protected $email;
/**
* Set email
*
* @param boolean $email
* @return email
*/
public function setEmail($email) {
$this->email = $email;
return $this;
}
/**
* Get email
*
* @return boolean
*/
public function getEmail() {
return $this->email;
}
/**
* @var boolean
*
* @ORM\Column(name="areacode", type="integer", nullable=true)
* @V2Assert\AreaCode
*/
protected $areacode;
/**
* Set areacode
*
* @param $areacode
* @return areacode
*/
public function setAreacode($areacode) {
$this->areacode = $areacode;
return $this;
}
/**
* Get areacode
*
* @return boolean
*/
public function getAreacode() {
return $this->areacode;
}
/**
* Set background
*
* @param $background
* @return background
*/
public function setBackground($background) {
$this->background = $background;
return $this;
}
/**
* Get background
*
* @return boolean
*/
public function getBackground() {
return $this->background;
}
}
class Staff extends Person
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var \Truckee\VolunteerBundle\Entity\Organization
*
* @ORM\ManyToOne(targetEntity="Truckee\VolunteerBundle\Entity\Organization", inversedBy="staff", cascade={"persist","remove"})
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="orgId", referencedColumnName="id")
* })
*/
protected $organization;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set organization
*
* @param \Truckee\VolunteerBundle\Entity\Organization $organization
* @return Staff
*/
public function setOrganization(\Truckee\VolunteerBundle\Entity\Organization $organization = null)
{
$this->organization = $organization;
return $this;
}
/**
* Get organization
*
* @return \Truckee\VolunteerBundle\Entity\Organization
*/
public function getOrganization()
{
return $this->organization;
}
}
答案 0 :(得分:3)
AFAIK错误是因为您的联接缺少标准。这是由Doctrine编写的代码的摘录:
FROM opportunity o0_
INNER JOIN organization o1_
ON (o0_.orgId = o1_.id)
INNER JOIN staff s2_ <-- MISSING CRITERIA HERE
INNER JOIN person p3_
ON s2_.id = p3_.id AND (s2_.orgId = o1_.id)
LEFT JOIN admin_outbox a4_
ON (o0_.id = a4_.oppId AND a4_.functionName = 'expiringAlertsAction')
您应该仔细检查您的实体定义。
答案 1 :(得分:0)
特别感谢@FrancescoAbeni让我走上正轨。最初的item_vec.last().unwrap().clone()
反映了其他地方被替换的逻辑。我重写了代码来创建以下内容,允许Doctrine保留连接条件。
值得注意的是,对于这个应用程序,我还需要添加orocrm/doctrine-extensions才能拥有MySQL&amp; PostgreSQL expiringOppsSent()
和month()
函数。另外,我必须在pgAdmin查询中year()
。
CREATE EXTENSION fuzzystrmatch