rah*_*ele 5 sql sql-server database-connection go
我试图使用带有Go程序的Microsoft SQL Server连接到SQL Server中的数据库并从数据库中读取一些数据.
但是,当我使用err=db.ping()它时会导致错误,该错误表示:
用户'sakhaloo'登录失败
我从这个目录下载了驱动程序包的zip文件:github.com/denisenkom/go-mssqldb然后我复制压缩文件中的文件并将它们粘贴到以下地址:C:\Go\src\github.com\denisenkom\go-mssqldb
另一个问题是,当我尝试使用SQL Server 2014 Management Studio打开我的SQL数据库时,它不接受我的用户名或密码,实际上当我输入用户名和密码时会导致此错误:
已成功与服务器建立连接,但在登录过程中发生错误.(提供程序:共享内存提供程序,错误:0 - 管道的另一端没有进程.)(Microsoft SQL Server,错误:233)
我不知道这个过程有什么问题.
这是我的代码:
package main
import (
//_ "code.google.com/p/odbc"
_ "github.com/denisenkom/go-mssqldb"
"database/sql"
"fmt"
"log"
//"github.com/astaxie/beedb"
// "github.com/weigj/go-odbc"
)
var (
uName, pass string
p *Person
)
type Person struct {
userName string
passWord string
Email string
}
func main() {
db, err := sql.Open("mssql", "server=SAKHALOO-PC;user id=sakhaloo;password=hoollehayerazi;database=webApp" )
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("Please enter your full name & password:")
fmt.Scanln(&uName, &pass)
row := db.QueryRow("SELECT username, password, email FROM user WHERE username=? and password=?", uName, pass)
fmt.Println(row)
p := new(Person)
err = row.Scan(&p.userName, &p.passWord, &p.Email)
fmt.Printf("%s , %s , %s \n", p.userName, p.passWord, p.Email)
fmt.Printf("Hi %s, your email address is : %s", uName, p.Email)
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*ers 11
我想分享我使用SQL Server Express 2008编写一个简单的演示Go语言数据库程序的经验.我相信以下经验教训将适用于2008年及以后的任何SQL Server版本.
我的SQL Server Express以前是与default实例一起安装的,而不是named实例.它还安装使用Windows身份验证.我做的其他开发工作都需要这两个设置.我做的其他工作在同一台PC上使用SQL Server Express作为本地数据库引擎.我希望能够在Go应用程序中使用Windows身份验证和SQL Server.
寻找一个驱动程序和一个小示例程序与本地SQL Server和Go一起使用,我的搜索出现了这个问题.我想添加一些额外的信息和示例程序,以帮助其他人开始并从我的错误中吸取教训.我还发现这篇文章GoLang和MSSQL数据库:一个例子有用,特别是在我犯了足够的错误之后我更了解它.
我的测试程序的最终版本如下:
package main
import (
"fmt"
"log"
"database/sql"
_ "github.com/denisenkom/go-mssqldb" // the underscore indicates the package is used
)
func main() {
fmt.Println("starting app")
// the user needs to be setup in SQL Server as an SQL Server user.
// see create login and the create user SQL commands as well as the
// SQL Server Management Studio documentation to turn on Hybrid Authentication
// which allows both Windows Authentication and SQL Server Authentication.
// also need to grant to the user the proper access permissions.
// also need to enable TCP protocol in SQL Server Configuration Manager.
//
// you could also use Windows Authentication if you specify the fully qualified
// user id which would specify the domain as well as the user id.
// for instance you could specify "user id=domain\\user;password=userpw;".
condb, errdb := sql.Open("mssql", "server=localhost;user id=gouser;password=g0us3r;")
if errdb != nil {
fmt.Println(" Error open db:", errdb.Error())
}
defer condb.Close()
errdb = condb.Ping()
if errdb != nil {
log.Fatal(errdb)
}
// drop the database if it is there so we can recreate it
// next we will recreate the database, put a table into it,
// and add a few rows.
_, errdb = condb.Exec("drop database mydbthing")
if errdb != nil {
fmt.Println(" Error Exec db: drop db - ", errdb.Error())
}
_, errdb = condb.Exec("create database mydbthing")
if errdb != nil {
fmt.Println(" Error Exec db: create db - ", errdb.Error())
}
_, errdb = condb.Exec("use mydbthing")
if errdb != nil {
fmt.Println(" Error Exec db: using db - ", errdb.Error())
}
_, errdb = condb.Exec("create table junky (one int, two int)")
if errdb != nil {
fmt.Println(" Error Exec db: create table - ", errdb.Error())
}
_, errdb = condb.Exec("insert into junky (one, two) values (101, 201)")
if errdb != nil {
fmt.Println(" Error Exec db: insert table 1 - ", errdb.Error())
}
_, errdb = condb.Exec("insert into junky (one, two) values (102, 202)")
if errdb != nil {
fmt.Println(" Error Exec db: insert table 2 - ", errdb.Error())
}
_, errdb = condb.Exec("insert into junky (one, two) values (103, 203)")
if errdb != nil {
fmt.Println(" Error Exec db: insert table 3 - ", errdb.Error())
}
// Now that we have our database lets read some records and print them.
var (
one int
two int
)
// documentation about a simple query and results loop is at URL
// http://go-database-sql.org/retrieving.html
// we use Query() and not Exec() as we expect zero or more rows to
// be returned. only use Query() if rows may be returned.
fmt.Println (" Query our table for the three rows we inserted.")
rows, errdb := condb.Query ("select one, two from junky")
defer rows.Close()
for rows.Next() {
err:= rows.Scan (&one, &two)
if err != nil {
fmt.Println(" Error Query db: select - ", err.Error())
} else {
fmt.Printf(" - one %d and two %d\n", one, two)
}
}
rows.Close()
errdb = rows.Err()
if errdb != nil {
fmt.Println(" Error Query db: processing rows - ", errdb.Error())
}
fmt.Println("ending app")
}
Run Code Online (Sandbox Code Playgroud)
一旦对SQL Server设置进行必要的更改,第一次运行上述应用程序,它将生成以下输出.由于第一次运行程序时数据库不存在,您将看到打印的错误消息.但是随后运行时数据库将存在,并且不会输出数据库丢弃时的错误消息.
starting app
Error Exec db: drop db - mssql: Cannot drop the database 'mydbthing', because it does not exist or you do not have permission.
Query our table for the three rows we inserted.
- one 101 and two 201
- one 102 and two 202
- one 103 and two 203
ending app
Run Code Online (Sandbox Code Playgroud)
安装SQL Server驱动程序包
我要做的第一件事是找到一个可以与SQL Server一起使用的数据库驱动程序包.建议github.com/denisenkom/go-mssqldb使用几个stackoverflow发布的内容.
为了使用该github.com/denisenkom/go-mssqldb包,我必须首先使用go get github.com/denisenkom/go-mssqldb运行创建的命令shell窗口从github存储库中检索它Git Shell.
Git Shell是作为安装Git的一部分安装的github shell.我发现,我已经运行go get的命令Git Shell,以使go命令来查找git应用程序和访问GitHub的仓库.当我尝试go get从正常的命令shell 运行该命令时,我看到一条错误消息,指示git无法找到该命令.
安装go-mssqldb包之后,我能够运行我的示例应用程序并继续运行来自的运行时错误Open().我的应用程序的输出如下:
starting app
Error Exec db: create db - Unable to open tcp connection with host 'localhost:1433': dial tcp 127.0.0.1:1433: connectex: No connection could be made because the target machine actively refused it.
ending app
Run Code Online (Sandbox Code Playgroud)
为SQL Server启用TCP连接
经过一些搜索,我发现了许多不同的网站,这些网站都表明错误意味着我的SQL Server实例没有配置为TCP/IP.各种帖子表明我需要使用它Sql Server Configuration Manager来启用TCP/IP.
我发现实际上有两个地方需要启用TCP/IP.一个是Client Protocols,而且确实已经启用了.然而另一个是,Protocols for MSSQLSERVER并且在那个TCP/IP被禁用.因此,我在该Protocols for MSSQLSERVER部分中启用了TCP/IP ,然后使用"控制面板"中"管理工具"的"服务"实用程序重新启动了SQL Server服务.

但是在使用后我仍然遇到任何类型的查询问题sql.Open().我看到应用程序输出是以下的一些变化.错误消息是相同的,但是当函数调用有错误时可能会从一次运行更改为下一次运行.我尝试更改sql.Open()除了不同的错误消息之外没有结果的指定的连接字符串.
starting app
Error Exec db: create db - driver: bad connection
Error Exec db: create table - driver: bad connection
ending app
Run Code Online (Sandbox Code Playgroud)
进一步探索我在github存储库中找到了这个注释:
已知的问题
未禁用SSL加密时,SQL Server 2008和2008 R2引擎无法处理登录记录.若要解决SQL Server 2008 R2问题,请安装SQL Server 2008 R2 Service Pack 2.要修复SQL Server 2008问题,请为SQL Server 2008 SP3安装Microsoft SQL Server 2008 Service Pack 3和累积更新包3.更多信息:http: //support.microsoft.com/kb/2653857
所以我下载了我从未实际安装过的更新.而在下载等待,我戳各地越来越发现包含实际的SQL Server可执行与沿文件夹Log包含一系列文件夹ERRORLOG,ERRORLOG.1等等.
SQL Server日志表明需要SQL Server用户
在ERRORLOG文件中查找我发现SQL Server的错误日志,其中包含以下日志,这些日志提供了下一个难题:
2016-08-15 22:56:22.41 Server SQL Server is now ready for client connections. This is an informational message; no user action is required.
2016-08-15 23:55:47.51 Logon Error: 18456, Severity: 14, State: 58.
2016-08-15 23:55:47.51 Logon Login failed for user 'rchamber'. Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only. [CLIENT: 127.0.0.1]
2016-08-15 23:55:47.61 Logon Error: 18456, Severity: 14, State: 58.
2016-08-15 23:55:47.61 Logon Login failed for user 'rchamber'. Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only. [CLIENT: ::1]
2016-08-15 23:55:47.62 Logon Error: 18456, Severity: 14, State: 58.
2016-08-15 23:55:47.62 Logon Login failed for user 'rchamber'. Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only. [CLIENT: 127.0.0.1]
Run Code Online (Sandbox Code Playgroud)
然后我意识到Go SQL Server驱动程序没有使用Windows身份验证,而是使用SQL Server身份验证.我试图通过指定一个空来尝试使用Windows身份验证,user id=但这似乎不起作用.因此,使用该sqlcmd实用程序,我创建了一个SQL Server用户.
1> create login gouser with password='g0us3r';
2> go
1> create user gouser for login gouser;
2> go
Run Code Online (Sandbox Code Playgroud)
接下来,我下载并安装了Microsoft SQL Server Management Studio.这是与SQL Server配置管理器不同的实用程序.使用这个我做了两件事:(1)打开SQL Server身份验证以及Windows身份验证,(2)为我的新SQL Server用户提供必要的权限gouser.该实用程序还提供了一个很好的用户界面来浏览SQL Server及其各种数据库.
确保您创建的SQL用户具有足够的权限,以便可以使用它来连接到SQL Server并创建数据库.
使用Windows身份验证的一些注意事项
经过进一步研究后,我发现我实际上可以使用Windows身份验证,但必须提供完全限定的用户ID和密码.对于使用域名为"AD"的Active Directory的环境,完全限定的用户ID为"AD\userid",本地主机的用户ID为"\ userid".我仍然在研究能够自动使用当前登录用户的凭据.
在进一步研究并从Go驱动程序开发人员那里寻求帮助之后,如果sql.Open()不包含意味着"user id =; password =;"的用户信息,则应该可以使用当前的Windows身份验证.不应该指定.
但是,只有在SQL Server实例使用具有有效服务主体名称(SPN)的Kerberos时,才允许针对当前用户进行这种形式的自动Windows身份验证.如果在SQL Server实例上执行重新启动,并且在ERRORLOG文件中看到以下日志,则SQL Server无法使用Kerberos进行初始化.
2016-08-23 18:32:16.77服务器SQL Server网络接口库无法注册SQL Server服务的服务主体名称(SPN).错误:0x54b,状态:3.无法注册SPN可能导致集成身份验证回退到NTLM而不是Kerberos.这是一条情报信息.只有在身份验证策略需要Kerberos身份验证时,才需要采取进一步操作.
另请参阅如何在创建与SQL Server 2005实例的远程连接时确保使用Kerberos身份验证,该实例还提供了一些其他信息以及使用该setspn命令来更正问题.
另请参见SQL网络接口库无法注册SPN.
关于受信任的Windows身份验证(根据@xdhard的请求更新@xpt)
Windows身份验证使用Windows凭据登录到SQL Server,而不指定用户标识和密码.这称为sqlcmd或的可信连接ODBC; 或者称为go-mssqldbGo - driver包的Single-Sign-On .
来自go-mssqldbgithub的自述文件,
"user id" - 以DOMAIN\User格式输入SQL Server身份验证用户ID或Windows身份验证用户ID.在Windows上,如果用户标识为空或缺少使用单点登录.
所以我尝试了以下两种方式使用我的SQL Server 2008 R2,两者都运行良好:
condb, errdb := sql.Open("mssql", "server=MyServer;user id=;password=DONTCARE;")
condb, errdb := sql.Open("mssql", "server=MyServer;user id=;password=;")
Run Code Online (Sandbox Code Playgroud)
请注意,使用server = localhost会失败,因为拥有正确的主机名很重要,从该名称驱动程序正在构建SQL Server kerberos服务主体名称(SPN),并且该名称必须与SQL Server匹配.我在测试中使用了正确的服务主体名称(SPN),因此它可以工作.