So this DB query doesn't work unless I Sprintf into a string first. Why?

polaris · · 686 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I am using PostgreSQL and have used db.Query before in a similar way, but for some reason when using PostGIS functions it does not work. What am I missing?</p> <p>This works (however, obviously unsafe unsanitized data)</p> <pre><code>query := fmt.Sprintf(`SELECT id, ST_X(location::geometry) as lng, ST_Y(location::geometry) as lat, photo_ext, name, last_updated::DATE as lu FROM locations WHERE ST_Distance_Sphere( ST_GeomFromText( &#39;POINT(%f %f)&#39;,4326 ), ST_GeomFromText( &#39;POINT(&#39; || ST_X(location::geometry) || &#39; &#39; || ST_Y(location::geometry) || &#39;)&#39;, 4326 ) ) &lt;= 30 * 1609.34`, lngF, latF, ) rows, err := db.Query(query) </code></pre> <p>pq: could not determine data type of parameter $1.</p> <pre><code>rows, err := db.Query(`SELECT id, ST_X(location::geometry) as lng, ST_Y(location::geometry) as lat, photo_ext, name, last_updated::DATE as lu FROM locations WHERE ST_Distance_Sphere( ST_GeomFromText( &#39;POINT($1 $2)&#39;,4326 ), ST_GeomFromText( &#39;POINT(&#39; || ST_X(location::geometry) || &#39; &#39; || ST_Y(location::geometry) || &#39;)&#39;, 4326 ) ) &lt;= 30 * 1609.34`, lngF, latF) </code></pre> <p>I&#39;ve tried various variations of the latter with zero success. Golang community, please help.</p> <hr/>**评论:**<br/><br/>wwader: <pre><p>Try to change POINT(%f %f) to POINT(? ?)</p></pre>NikkoTheGreeko: <pre><p>Well, it&#39;s actually POINT($1 $2) already. %f is from the unsafe Sprintf version which I want to avoid.</p></pre>wwader: <pre><p>Sorry i meant change POINT($1 $2) to POINT(? ?). Does that work?</p></pre>NikkoTheGreeko: <pre><p>Postgres&#39;s driver requires $1, $2, $3 etc... ?, ?, ? is for MySQL and I think some others.</p></pre>wwader: <pre><p>Ok! did not know placeholders where done by drivers... but that makes very much sense. Good to know!</p></pre>NikkoTheGreeko: <pre><p>Fortunately in this example I am able to convert to a float which sanitizes the values. There&#39;s another statement using user inputted text which scares me.</p></pre>Justinsaccount: <pre><p>What types are lngF and latF?</p></pre>NikkoTheGreeko: <pre><p>I&#39;ve tried float32, float64, and string with the same result.</p></pre>ephemient: <pre><p>Usually something like <code>$1::float4</code> or <code>$1::float8</code> would work, but in this case it looks like you actually want to interpolate into the <code>&#39;POINT()&#39;</code> as a string? I&#39;d probably use just a single placeholder and bind <code>fmt.Sprintf(&#34;POINT(%f %f)&#34;, lngF, latF)</code> as a string.</p></pre>mgutz: <pre><p>are you missing a comma? <code>point($1, $2)</code></p></pre>ChristophBerger: <pre><blockquote> <p>pq: could not determine data type of parameter $1.</p> </blockquote> <p>Of what data type are the parameters lngF anD latF? Maybe pq needs different types.</p> <p>Did you check the pq repository for any related issues?</p> <p>And what is the simplest query string that fails with this error message? Like, does <code>select * from table where a = $1</code> fail? (Try different types for the var that goes into $1)</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

686 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传