我有以下两个表:
table_a:
id_table_a: { type: integer, primaryKey: true, autoIncrement: true, required: true }
name: { type: varchar(255) }
id_table_b: { type: integer, foreignTable: table_b, foreignReference: id_table_b }
table_b:
id_table_b: { type: integer, primaryKey: true, autoIncrement: true, required: true }
value_1: { type: varchar(255) }
value_2: { type: integer }
我想使用 select 方法来构建 SQL 查询以跳过水合,也在连接的表上使用别名:
TableAQuery::create()
->useTableBQuery('a')
// some filters methods
->endUse()
->useTableBQuery('b')
// some filters methods
->endUse()
->select(array('a.value_1', 'b.value_2'))
->find();
现在问题来了。Propel 始终如一地不断更改a
和b
别名,以table_b
生成不正确的 SQL,如下所示:
SELECT table_b.value_1 AS "a.value_1", table_b.value_2 AS "b.value_2" FROM `table_a`
LEFT JOIN `table_b` `a` ON (table_a.id_table_b=a.id_table_b)
LEFT JOIN `table_b` `b` ON (table_a.id_table_b=b.id_table_b)
而不是
SELECT a.value_1 AS value_1, b.value_2 AS value_2 FROM `table_a`
LEFT JOIN `table_b` `a` ON (table_a.id_table_b=a.id_table_b)
LEFT JOIN `table_b` `b` ON (table_a.id_table_b=b.id_table_b)
我该如何处理?我使用推进 1.6.9
更新
我还检查了推进 1.7.1,没有区别。
在我读了张伯伦在他的回答下关于where
卡鲁斯的评论后,我做了一些研究,我得出的结论是
-
在 propel 函数中键入列名时,应始终使用
UpperCamelCase
样式,即使如果不使用此样式,它有时可以正常工作 - 解决方案取决于推进版本
可能没有针对 Propel <= 1.6.7 的解决方案(或者原始 SQL 查询是唯一的解决方案),因为无论我尝试多少,我总是以 Propel 异常Cannot fetch ColumnMap for undefined column: ID_TABLE_B
告终。
对于推进>= 1.6.8,这将起作用:
如果您需要带有别名列的数组作为结果
TableAQuery::create()
->useTableBQuery('a')
// some filters methods
->endUse()
->useTableBQuery('b')
// some filters methods
->endUse()
->select(array('a.Value1', 'b.Value2')) // notice a.value_1 or b.value_2 won't work
->find();
如果需要具有别名列中的虚拟列的对象
TableAQuery::create()
->useTableBQuery('a')
// some filters methods
->endUse()
->useTableBQuery('b')
// some filters methods
->endUse()
->withColumn('a.Value1') // notice a.value_1 won't work
->withColumn('b.Value2') // notice b.value_2 won't work
->find();
你能把它改成这个吗?
TableAQuery::create()
->useTableBQuery('a')
// some filters methods
->endUse()
->useTableBQuery('b')
// some filters methods
->endUse()
//->select(array('a.value_1', 'b.value_2'))
->addAsColumn('a.value_1', 'a.value_1')
->addAsColumn('b.value_2', 'b.value_2')
->find();
警告:我不是 Propel 用户。我只是想知道自动生成的useXXXQuery()
是否两次都在同一关系上设置表别名,或者类似的东西。
与上面的查询一样,将您的select()
替换为两个addAsColumn()
语句。这有点黑客,但我认为它达到了您想要的结果。
我刚刚花了一段时间阅读 Propel 源代码,得出的结论是,Propel 1 不是为了在多次连接的同一个表上使用不同的别名而构建的,正如你尝试的那样。在ModelCriteria.php
中,使用 $column->getFullyQualifiedName
可确保在选择连接表时使用全名 (table.column),而不考虑别名。(请参阅 https://github.com/propelorm/Propel/blob/7ddb0956b699343d33ce0c94043fa5970cc719c1/runtime/lib/query/ModelCriteria.php#L2082。我希望这确实是一个错误。
如果使用 addAsColumn()
方法而不是 select()
,Propel 将使用您的文字 SQL 表达式,无论是别名和列还是其他任何内容。也就是说,我不确定这是它的预期用途。