我正在尝试从C#执行参数化查询,我收到错误:
错误:XX000:解析错误 - 无效几何
提示
“POLYGON((:m”< - 几何中位置11处的解析错误
但是当我在pgAdmin III中运行查询时,用它们的值替换参数,查询就可以了。代码是
command.CommandText = "SELECT area_code FROM area WHERE ST_INTERSECTS(ST_GeographyFromText('POLYGON((:minx :miny, :minx :maxy, :maxx :maxy, :maxx :miny, :minx :miny))'), shape) AND area_type_code = :typecode";
command.CommandType = CommandType.Text;
var typeCodeParameter = new NpgsqlParameter
{
DbType = DbType.String,
ParameterName = "typecode",
Value = _typeCode
};
var minxParameter = new NpgsqlParameter
{
DbType = DbType.Double,
ParameterName = "minx",
Value = _minX
};
var minyParameter = new NpgsqlParameter
{
DbType = DbType.Double,
ParameterName = "miny",
Value = _minY
};
var maxxParameter = new NpgsqlParameter
{
DbType = DbType.Double,
ParameterName = "maxx",
Value = _maxX
};
var maxyParameter = new NpgsqlParameter
{
DbType = DbType.Double,
ParameterName = "maxy",
Value = _maxY
};
command.Parameters.Add(typeCodeParameter);
command.Parameters.Add(maxxParameter);
command.Parameters.Add(maxyParameter);
command.Parameters.Add(minxParameter);
command.Parameters.Add(minyParameter);
using (var reader = command.ExecuteReader())
while (reader.Read())
areas.Add((string)reader["area_code"]);
,工作查询
SELECT area_code FROM area WHERE ST_INTERSECTS(ST_GeographyFromText('POLYGON((-1.0042576967558934 50.78431084582985, -1.0042576967558934 51.199216033050647, 1.9400782407441057 51.199216033050647, 1.9400782407441057 50.78431084582985, -1.0042576967558934 50.78431084582985))'), shape) AND area_type_code = 'County'
我做错了什么?我该如何设置minx,miny,maxx,maxy参数?
答案 0 :(得分:2)
问题是你要分离坐标。这些参数不仅仅是在SQL内部(它不仅仅是模板替换),它需要是一个语法上有效的放置参数的地方。一个好的健全性检查是尝试相同的查询,但不是直接用值替换参数,而是使用过程SQL和变量。
您将看到问题是ST_GeographyFromText
函数没有扩展输入所在字符串内的参数 - 这是预期的行为。如果你想使用这个功能,你不能在字符串里面使用参数 - 你仍然只需要所有的值并将它们作为一个字符串传递 - 就像你做的那样#&#c; 34;删除参数"。最简单的解决方案可能是将整个字符串作为参数传递,或者只是将参数添加到查询中的字符串中(例如ST_GeographyFromText('POLYGON((' || cast(:minx ...) || '), ' || ... || ')')
等)。
似乎你正在转换旧的"连接一堆字符串"带参数化查询的SQL。坚持下去,但你需要考虑语法。就像你不能将子查询放在参数中一样,你不能只将一个值分成两个这样的参数。
所以你需要使用更好的类型,或者有一些辅助转换(比如一个需要两个浮点数的函数,并返回你需要的类型)。
答案 1 :(得分:1)
使用此参数化查询的正确方法是使用一个函数,该函数使用数字参数构建包络,例如ST_MakeEnvelope(xmin, ymin, xmax, ymax)。
SELECT area_code
FROM area
WHERE ST_Intersects(ST_MakeEnvelope(:minx, :miny, :maxx, :maxy)::geography, shape)
AND area_type_code = :typecode;
格式化文本的其他尝试(WKT)速度慢且有损,因为数字会转换为文本,然后再解析为数字。