我正在尝试获取点列表,并查询地理空间数据库以查找所有匹配的行。
我有一条经过计算的SQL语句,如下所示:
cursor = connection.cursor()
cursor.execute(
'''
SELECT g.ident
FROM (VALUES %s) AS v (lon, lat)
LEFT JOIN customers g
ON (ST_Within(ST_SetSRID(ST_MakePoint(v.lon, v.lat), %s), g.poly_home));
''', [AsIs(formatted_points), SRID]
)
以下是formatted_points变量的示例:
(-115.062,38.485), (-96.295,43.771)
因此,当将其插入到SQL表达式中时,VALUES表达式将读取:
(VALUES (-115.062,38.485), (-96.295,43.771)) AS v (lon, lat)
到目前为止,一切都很好。但是,当点列表为空时,VALUES表达式如下所示:
(VALUES ) AS v (lon, lat)
..这导致我收到此错误:
django.db.utils.ProgrammingError: syntax error at or near ")"
换句话说,(VALUES )
不是合法的SQL。
这是问题:如何使用VALUES表示空白列表?我可以对此进行特殊处理,并在此函数传递一个空列表时只返回一个空列表,但这似乎并不十分优雅。
我已经看过PostgreSQL manual page中的VALUES,但是我不明白如何构造一个空的VALUES表达式。
答案 0 :(得分:1)
如果您可以将lons和lats放在单独的数组中,则可以使用带有unnest的数组:
select * from unnest(ARRAY[1, 2, 3]::int[], ARRAY[4, 5, 6]::int[]) as v(lon, lat);
lon | lat
-----+-----
1 | 4
2 | 5
3 | 6
(3 rows)
select * from unnest(ARRAY[]::int[], ARRAY[]::int[]) as v(lon, lat);
lon | lat
-----+-----
(0 rows)
您必须将数组转换为适当的类型(可能不是int [])。如果数组不为空,则Postgres会猜测类型,但是如果数组为空,并且您不将其强制转换为特定类型,它将引发错误。