英文:
See query with arguments in Go database/sql package
问题
我正在尝试测试将参数传递给sql.DB.Query方法的行为(使用database/sql包和PostgreSQL驱动程序在github.com/lib/pq上)。有没有办法在处理后获取原始查询字符串,以查看参数是如何插入的?我在考虑,例如,编写一个预处理查询,然后检查生成的语句。有什么想法吗?谢谢!
英文:
I'm trying to test the behavior of passing arguments to the sql.DB.Query method (using the database/sql package, and the PostgreSQL driver at github.com/lib/pq). Is there any way to get the raw query string after it's been processed to see how the arguments were inserted? I was thinking, for example, of writing a prepared query and then inspecting the resulting statement. Any ideas? Thanks!
答案1
得分: 5
“原始查询字符串”不会被客户端解析和插值;它会完整地传递给服务器。
如果查询没有参数,客户端将其作为“简单查询”发送;如果查询有参数,客户端将其作为“扩展查询”发送,其中参数与查询分开。然后服务器解析查询并将其参数化。
Go的database/sql
不包含任何日志记录功能,所以你要么需要自己编写日志记录功能,要么使用Wireshark来嗅探流量,或者在服务器端启用日志记录。
英文:
The "raw query string" isn't parsed by the client and interpolated; it's passed on intact to the server.
If the query has no parameters, the client sends it as a simple query; if the query has parameters, the client sends it as an extended query with the parameters separate from the query. The server then parses the query and parameterizes it.
Go's database/sql
doesn't include any logging, so you'll either have to write your own, sniff the traffic with Wireshark, or enable logging on the server side.
答案2
得分: 4
看起来它并没有在查询本身中插入参数。它发送查询,然后等待响应以发送参数。我分叉了pq并在其中放置了一些日志代码 - 这是一个简单查询的输出:
wes-macbook:testpq go run testpq.go
2014/01/03 19:08:56 bytes: [0 0 0 84 0 3 0 0 101 120 116 114 97 95 102 108 111 97 116 95 100 105 103 105 116 115 0 50 0 99 108 105 101 110 116 95 101 110 99 111 100 105 110 103 0 85 84 70 56 0 100 97 116 101 115 116 121 108 101 0 73 83 79 44 32 77 68 89 0 117 115 101 114 0 119 102 114 101 101 109 97 110 0 0]
2014/01/03 19:08:56 string: Textra_float_digits2client_encodingUTF8datestyleISO, MDYuserwfreeman
2014/01/03 19:08:56 bytes: [80 0 0 0 45 0 115 101 108 101 99 116 32 42 32 102 114 111 109 32 116 101 115 116 32 119 104 101 114 101 32 116 101 115 116 46 110 97 109 101 61 36 49 0 0 0]
2014/01/03 19:08:56 string: P-select * from test where test.name=$1
2014/01/03 19:08:56 bytes: [68 0 0 0 6 83 0]
2014/01/03 19:08:56 string: DS
2014/01/03 19:08:56 bytes: [83 0 0 0 4]
2014/01/03 19:08:56 string: S
2014/01/03 19:08:56 bytes: [66 0 0 0 20 0 0 0 0 0 1 0 0 0 4 97 115 100 102 0 0]
2014/01/03 19:08:56 string: Basdf
2014/01/03 19:08:56 bytes: [69 0 0 0 9 0 0 0 0 0]
2014/01/03 19:08:56 string: E
2014/01/03 19:08:56 bytes: [83 0 0 0 4]
2014/01/03 19:08:56 string: S
我所做的只是调整了send()代码:
func (cn *conn) send(m *writeBuf) {
b := (*m)[1:]
binary.BigEndian.PutUint32(b, uint32(len(b)))
if (*m)[0] == 0 {
*m = b
}
// 新代码在这里
log.Println("bytes:", *m)
log.Println("string:", string(*m))
_, err := cn.c.Write(*m)
if err != nil {
panic(err)
}
}
我的示例代码,虽然相当简单:
https://gist.github.com/8249430
英文:
It doesn't look like it inserts parameters in the query itself. It sends the query, then waits for the response to send parameters. I forked pq and put some logging code in--this was the output for a simple query:
wes-macbook:testpq go run testpq.go
2014/01/03 19:08:56 bytes: [0 0 0 84 0 3 0 0 101 120 116 114 97 95 102 108 111 97 116 95 100 105 103 105 116 115 0 50 0 99 108 105 101 110 116 95 101 110 99 111 100 105 110 103 0 85 84 70 56 0 100 97 116 101 115 116 121 108 101 0 73 83 79 44 32 77 68 89 0 117 115 101 114 0 119 102 114 101 101 109 97 110 0 0]
2014/01/03 19:08:56 string: Textra_float_digits2client_encodingUTF8datestyleISO, MDYuserwfreeman
2014/01/03 19:08:56 bytes: [80 0 0 0 45 0 115 101 108 101 99 116 32 42 32 102 114 111 109 32 116 101 115 116 32 119 104 101 114 101 32 116 101 115 116 46 110 97 109 101 61 36 49 0 0 0]
2014/01/03 19:08:56 string: P-select * from test where test.name=$1
2014/01/03 19:08:56 bytes: [68 0 0 0 6 83 0]
2014/01/03 19:08:56 string: DS
2014/01/03 19:08:56 bytes: [83 0 0 0 4]
2014/01/03 19:08:56 string: S
2014/01/03 19:08:56 bytes: [66 0 0 0 20 0 0 0 0 0 1 0 0 0 4 97 115 100 102 0 0]
2014/01/03 19:08:56 string: Basdf
2014/01/03 19:08:56 bytes: [69 0 0 0 9 0 0 0 0 0]
2014/01/03 19:08:56 string: E
2014/01/03 19:08:56 bytes: [83 0 0 0 4]
2014/01/03 19:08:56 string: S
All I did was tweak the send() code:
func (cn *conn) send(m *writeBuf) {
b := (*m)[1:]
binary.BigEndian.PutUint32(b, uint32(len(b)))
if (*m)[0] == 0 {
*m = b
}
// new code here
log.Println("bytes:", *m)
log.Println("string:", string(*m))
_, err := cn.c.Write(*m)
if err != nil {
panic(err)
}
}
My sample code, although it's pretty trivial:
https://gist.github.com/8249430
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论