在Go的database/sql包中查看带参数的查询。

huangapple go评论103阅读模式
英文:

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

huangapple
  • 本文由 发表于 2014年1月4日 06:14:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/20913669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定