wie man wiederholt
db.Query ("set @ a = 1")
db.Query ("select @a")
return null
Dies scheint darauf zurückzuführen zu sein, dass das Laufwerk bei der Ausführung von "select @a" eine neue Sitzung auf dem MySQL-Server erstellt. Dies führt dazu, dass Sitzungsvariablen nicht verwendet werden können.
Ist der Mechanismus von database / sql oder github.com/go-sql-driver/mysql betroffen?
Mit Ihrem bereitgestellten Beispielcode sind zwei Dinge falsch:
1) db.Query
gibt rows
das geschlossen oder vollständig gelesen werden muss (was es implizit schließt). Andernfalls wird die Verbindung blockiert und kann nicht für andere Abfragen wiederverwendet werden.
2) Wie Sie bereits vermutet haben, erstellt die 2. db.Query in den meisten Fällen eine neue Sitzung, da nicht garantiert wird, dass sie auf derselben Verbindung ausgeführt wird. Derzeit besteht die einzige Möglichkeit, eine Verbindung über die Datenbank- / SQL-Schnittstelle von Go zu reservieren, in der Verwendung von Transaktionen: http://golang.org/pkg/database/sql/#DB.Begin
Ich würde Ihnen empfehlen, das Datenbank- / SQL-Tutorial unter http://go-database-sql.org/ zu lesen.
Es kann eine neue Sitzung erstellen, es kann dieselbe verwenden. Wir wissen es nicht, es hängt vollständig vom Pooling um database/sql
und wir können nichts tun, um es zu ändern.
Sie können
database/sql
SELECT
initialisiert werdenMein Rezept für das letzte:
SET <strong i="17">@row</strong> := 0;
SELECT <strong i="18">@row</strong> := <strong i="19">@row</strong> + 1, * FROM mytable;
wird
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;
Es können jedoch nicht alle Anweisungen in eine einzelne Anweisung geschrieben werden.
wie
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()
Es wird "gemischt" gedruckt, was der globale Wert ist.
Für Comman-Benutzer sieht es wie ein Fehler aus.
Obwohl es an der Datenbank / SQL liegt, gibt es etwas, das getan werden kann, um mit einem solchen Fall umzugehen?
Was meinst du mit Arnehormann unter "Treiber ohne Datenbank / SQL verwenden"? Erstellen Sie faild, ohne dieses Paket zu importieren
@tbdingqi Nein, nicht alle können in eine einzige Anweisung geschrieben werden. Aber einige der SET
Probleme können auf diese Weise gelöst werden.
Für einen normalen Benutzer sieht es wie ein Fehler aus:
Wir können nichts tun und etwas, das Sie tun können. Ich habe diese Dinge aufgelistet.
Wenn etwas anderes getan werden könnte, hätten wir es getan oder würden es tun, sobald wir können.
Bitte lesen Sie das Tutorial, mit dem Julien verlinkt ist. Es beschreibt die Einschränkungen der API ziemlich gut.
Der Import: Sie können stattdessen import "github.com/go-sql-driver/mysql"
verwenden
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
und sprechen Sie direkt mit dem Fahrer ohne database/sql
.
In Ihrem Beispielcode, der das Binlog-Format gedruckt hat, haben Sie geschrieben
trx ,: = db.Begin ()
db.Query ("set binlogformat = row")
Zeilen, _: = db.Query ("select @@ binlog_format")
Sie können dort nicht auf die Variable db zugreifen. Sie müssen dies stattdessen tun:
trx, err: = db.Begin ()
trx.Query (...)
Beachten Sie, dass ich mit trx abfrage, nicht mit db.
Möglicherweise müssen wir im Tutorial klarere Beispiele dafür geben
"Sitzungen" mit Transaktionen, die dies hervorheben. Wenn das Tutorial nicht ist
klar für Sie, bitte melden Sie einen Fehler an
https://github.com/VividCortex/go-database-sql-tutorial/issues
@xaprb guter Fang, ich habe den Tx-Missbrauch verpasst.
Diese Methode funktioniert nicht für Variablen wie sql_log_bin
.
MySQL selbst gibt einen Fehler aus:
ERROR 1694 (HY000): Cannot modify @@session.sql_log_bin inside a transaction
Gibt es eine Möglichkeit, diese Variable für *sql.DB
einzurichten?
Hilfreichster Kommentar
In Ihrem Beispielcode, der das Binlog-Format gedruckt hat, haben Sie geschrieben
trx ,: = db.Begin ()
db.Query ("set binlogformat = row")
Zeilen, _: = db.Query ("select @@ binlog_format")
Sie können dort nicht auf die Variable db zugreifen. Sie müssen dies stattdessen tun:
trx, err: = db.Begin ()
trx.Query (...)
Beachten Sie, dass ich mit trx abfrage, nicht mit db.
Möglicherweise müssen wir im Tutorial klarere Beispiele dafür geben
"Sitzungen" mit Transaktionen, die dies hervorheben. Wenn das Tutorial nicht ist
klar für Sie, bitte melden Sie einen Fehler an
https://github.com/VividCortex/go-database-sql-tutorial/issues