Mysql: variabel sesi tidak dapat digunakan?

Dibuat pada 23 Jan 2014  ·  7Komentar  ·  Sumber: go-sql-driver/mysql

bagaimana mengulang
db.Query ("set @ a = 1")
db.Query ("pilih @a")

mengembalikan nol

Tampaknya karena ketika "pilih @a" dijalankan, drive membuat sesi baru di server mysql. Hal ini menyebabkan variabel sesi tidak dapat digunakan.

Apakah mekanisme tersebut terkait dengan database / sql atau github.com/go-sql-driver/mysql?

databassql issue question

Komentar yang paling membantu

Dalam kode sampel Anda yang mencetak format binlog, Anda menulis

trx,: = db.Begin ()
db.Query ("set binlogformat = row")
baris, _: = db.Query ("pilih @@ binlog_format")

Anda tidak dapat mengakses variabel db di sana; Anda perlu melakukan ini sebagai gantinya:

trx, err: = db.Begin ()
trx.Query (...)

Perhatikan bahwa saya melakukan kueri dengan trx, bukan db.

Kami mungkin perlu memberikan contoh yang lebih jelas dalam tutorial tentang cara melakukannya
"sesi" dengan transaksi, menyoroti ini. Jika tutorialnya tidak
jelas bagi Anda, harap laporkan bug ke
https://github.com/VividCortex/go-database-sql-tutorial/issues

Semua 7 komentar

Ada dua hal yang salah dengan kode contoh yang Anda berikan:
1) db.Query mengembalikan rows yang harus ditutup atau dibaca seluruhnya (yang secara implisit menutupnya). Jika tidak, koneksi akan diblokir dan tidak dapat digunakan kembali untuk pertanyaan lain.
2) Seperti yang sudah Anda tebak, db.Query ke-2 membuat sesi baru dalam banyak kasus, karena tidak dijamin akan dijalankan pada koneksi yang sama. Saat ini satu-satunya cara untuk memesan koneksi melalui antarmuka database / sql Go adalah dengan menggunakan transaksi: http://golang.org/pkg/database/sql/#DB.Begin

Saya akan merekomendasikan Anda untuk membaca tutorial database / sql di http://go-database-sql.org/

Ini mungkin membuat sesi baru, mungkin menggunakan yang sama. Kami tidak tahu, itu sepenuhnya tergantung pada penggabungan oleh database/sql dan tidak ada yang dapat kami lakukan untuk mengubahnya.

Kamu bisa

  • mengajukan masalah untuk menambahkan dukungan sesi ke Go dan berharap itu ditambahkan dengan cepat
  • lakukan dalam transaksi (yang menggunakan koneksi yang sama untuk semua kueri)
  • gunakan driver tanpa database/sql
  • gunakan tidak aman untuk mengekstrak koneksi
  • tulis ulang kueri Anda sehingga variabel diinisialisasi pada SELECT

Resep saya untuk yang terakhir:

SET <strong i="17">@row</strong> := 0;
SELECT <strong i="18">@row</strong> := <strong i="19">@row</strong> + 1, * FROM mytable;

menjadi

SELECT <strong i="23">@row</strong> := <strong i="24">@row</strong> + 1, t.* FROM (SELECT <strong i="25">@row</strong> := 0) cnt JOIN mytable t;

Tetapi tidak semua pernyataan dapat ditulis menjadi satu pernyataan.
sebagai

   db, _ := sql.Open("mysql", connect_string)

   trx, _:= db.Begin()
   db.Query("set binlog_format=row")

   rows, _ := db.Query("select @@binlog_format")
   for rows.Next() {
     var v string
     rows.Scan(&v)
     fmt.Println(v)
   }   
   rows.Close()

   trx.Commit()
   db.Close()

Ini mencetak "campuran", yang merupakan nilai global.

Untuk pengguna comman, ini terlihat seperti bug.
Padahal karena database / sql, adakah yang bisa dilakukan untuk menangani kasus seperti itu?

untuk arnehormann, apa yang Anda maksud dengan "menggunakan driver tanpa database / sql"? Tanpa mengimpor paket ini, build faild

@tbdingqi Tidak, tidak semua dapat ditulis menjadi satu pernyataan. Tetapi beberapa masalah SET dapat diselesaikan dengan cara itu.

Sepertinya bug bagi pengguna biasa:
Tidak ada yang dapat kami lakukan dan beberapa hal yang dapat Anda lakukan. Saya mendaftar hal-hal itu.
Jika sesuatu yang lain bisa dilakukan, kami akan melakukannya atau akan melakukannya secepat kami bisa.
Silakan baca tutorial yang ditautkan ke Julien, ini menjelaskan batasan api yang cukup bagus.

Impor: Anda dapat menggunakan import "github.com/go-sql-driver/mysql" sebagai ganti

import (
  "database/sql"
  _  "github.com/go-sql-driver/mysql"
)

dan berbicara dengan pengemudi secara langsung tanpa database/sql .

Dalam kode sampel Anda yang mencetak format binlog, Anda menulis

trx,: = db.Begin ()
db.Query ("set binlogformat = row")
baris, _: = db.Query ("pilih @@ binlog_format")

Anda tidak dapat mengakses variabel db di sana; Anda perlu melakukan ini sebagai gantinya:

trx, err: = db.Begin ()
trx.Query (...)

Perhatikan bahwa saya melakukan kueri dengan trx, bukan db.

Kami mungkin perlu memberikan contoh yang lebih jelas dalam tutorial tentang cara melakukannya
"sesi" dengan transaksi, menyoroti ini. Jika tutorialnya tidak
jelas bagi Anda, harap laporkan bug ke
https://github.com/VividCortex/go-database-sql-tutorial/issues

@xaprb tangkapan yang bagus, saya melewatkan penyalahgunaan Tx.

Metode ini tidak akan berfungsi untuk variabel seperti sql_log_bin .
Mysql sendiri memberikan kesalahan:
ERROR 1694 (HY000): Cannot modify @@session.sql_log_bin inside a transaction

Apakah ada kesempatan untuk mengatur variabel ini untuk *sql.DB ?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat