Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Đi với trình điều khiển SQL Server không thể kết nối thành công, đăng nhập không thành công

Tôi muốn chia sẻ kinh nghiệm của mình khi tạo ra một chương trình cơ sở dữ liệu ngôn ngữ Go demo đơn giản bằng cách sử dụng SQL Server Express 2008. Tôi tin rằng những bài học kinh nghiệm sau đây sẽ áp dụng cho bất kỳ phiên bản SQL Server nào từ năm 2008 trở lên.

SQL Server Express của tôi trước đây đã được cài đặt với default ví dụ thay vì một named ví dụ. Nó cũng đã được cài đặt để sử dụng Windows Authentication. Cả hai cài đặt này đều được yêu cầu bởi công việc phát triển khác mà tôi thực hiện. Công việc khác mà tôi thực hiện sử dụng SQL Server Express trên cùng một PC làm ứng dụng làm công cụ cơ sở dữ liệu cục bộ. Tôi đã mong đợi có thể sử dụng Xác thực Windows với SQL Server trong ứng dụng Go của mình.

Đang tìm kiếm một trình điều khiển và một chương trình mẫu nhỏ để sử dụng với SQL Server và Go cục bộ, câu hỏi này đã xuất hiện trong tìm kiếm của tôi. Tôi nghĩ phải thêm một chút thông tin bổ sung và một chương trình mẫu để giúp những người khác bắt đầu và học hỏi từ những sai lầm của tôi. Tôi cũng thấy bài viết này Cơ sở dữ liệu GoLang và MSSQL:Một ví dụ hữu ích, đặc biệt là sau khi mắc đủ lỗi mà tôi hiểu rõ hơn.

Phiên bản cuối cùng của chương trình thử nghiệm của tôi như sau:

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")
}

Lần đầu tiên ứng dụng trên được chạy sau khi thực hiện các thay đổi cần thiết đối với cài đặt SQL Server, nó sẽ tạo ra kết quả sau. Vì cơ sở dữ liệu không tồn tại trong lần đầu tiên chương trình được chạy, bạn sẽ thấy thông báo lỗi được in. Tuy nhiên, những lần chạy tiếp theo, cơ sở dữ liệu sẽ tồn tại và thông báo lỗi khi cơ sở dữ liệu bị loại bỏ sẽ không tồn tại.

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

Cài đặt gói trình điều khiển SQL Server

Điều đầu tiên tôi phải làm là tìm một gói trình điều khiển cơ sở dữ liệu sẽ hoạt động với SQL Server. Một số bài đăng stackoverflow được đề xuất github.com/denisenkom/go-mssqldb vì vậy đó là những gì được sử dụng.

Để sử dụng github.com/denisenkom/go-mssqldb gói đầu tiên tôi phải truy xuất nó từ kho lưu trữ github bằng cách sử dụng go get github.com/denisenkom/go-mssqldb từ cửa sổ trình bao lệnh được tạo bằng cách chạy Git Shell .

Git Shell là github shell được cài đặt như một phần của quá trình cài đặt Git. Tôi thấy rằng tôi phải chạy go get trong Git Shell để go lệnh tìm git ứng dụng và truy cập kho lưu trữ github. Khi tôi cố gắng chạy go get lệnh từ trình bao lệnh bình thường Tôi thấy thông báo lỗi cho biết rằng git không thể tìm thấy lệnh.

Sau khi cài đặt go-mssqldb gói Tôi đã có thể chạy ứng dụng mẫu của mình và tiếp tục gặp lỗi thời gian chạy từ Open() . Kết quả từ ứng dụng của tôi như sau:

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

Bật kết nối TCP cho SQL Server

Sau một số tìm kiếm, tôi đã tìm thấy một số trang web khác nhau, tất cả đều chỉ ra rằng lỗi có nghĩa là phiên bản SQL Server của tôi không được định cấu hình cho TCP / IP. Các bài đăng khác nhau cho biết tôi cần sử dụng Sql Server Configuration Manager để bật TCP / IP.

Những gì tôi phát hiện ra là thực sự có hai nơi mà TCP / IP cần được kích hoạt. Một là Client Protocols và điều đó thực sự đã được kích hoạt. Tuy nhiên, cái khác là Protocols for MSSQLSERVER và trong đó một TCP / IP đã bị vô hiệu hóa. Vì vậy, tôi đã bật TCP / IP trong Protocols for MSSQLSERVER , sau đó khởi động lại dịch vụ SQL Server bằng tiện ích Dịch vụ của Công cụ quản trị từ Bảng điều khiển.

Tuy nhiên, tôi vẫn gặp sự cố với bất kỳ loại truy vấn nào sau khi sử dụng sql.Open() . Tôi đã thấy đầu ra ứng dụng là một số biến thể sau đây. Thông báo lỗi giống nhau, tuy nhiên khi các lệnh gọi hàm có lỗi có thể thay đổi từ lần chạy này sang lần chạy tiếp theo. Tôi đã thử thay đổi chuỗi kết nối được chỉ định trong sql.Open() không có kết quả nào ngoài các thông báo lỗi khác nhau.

starting app
  Error Exec db: create db -  driver: bad connection
  Error Exec db: create table -  driver: bad connection
ending app

Tìm hiểu kỹ hơn, tôi tìm thấy ghi chú này trong kho lưu trữ github:

Các vấn đề đã biết

Công cụ SQL Server 2008 và 2008 R2 không thể xử lý các bản ghi đăng nhập khi mã hóa SSL không bị tắt. Để khắc phục sự cố SQL Server 2008 R2, hãy cài đặt SQL Server 2008 R2 Gói Dịch vụ 2. Để khắc phục sự cố SQL Server 2008issue, hãy cài đặt Microsoft SQL Server 2008 Gói Dịch vụ 3 và Gói tích luỹ 3 cho SQL Server 2008 SP3. Thông tin thêm:http://support.microsoft.com/kb/2653857

Vì vậy, tôi đã tải xuống các bản cập nhật mà tôi chưa bao giờ thực sự cài đặt. Trong khi chờ tải xuống, tôi đã tìm kiếm xung quanh nhiều hơn và tìm thấy thư mục chứa tệp thực thi SQL Server thực cùng với Log thư mục chứa một loạt tệp ERRORLOG , ERRORLOG.1 , v.v.

Nhật ký SQL Server cho biết yêu cầu người dùng SQL Server

Tìm kiếm trong ERRORLOG tệp Tôi đã tìm thấy nhật ký lỗi của SQL Server với các nhật ký sau cung cấp phần tiếp theo của câu đố:

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]

Sau đó, tôi nhận ra rằng trình điều khiển Go SQL Server không sử dụng Xác thực Windows mà thay vào đó đang sử dụng Xác thực SQL Server. Tôi đã cố gắng sử dụng Xác thực Windows bằng cách chỉ định một user id= trống tuy nhiên điều đó dường như không hoạt động. Vì vậy, sử dụng sqlcmd tiện ích, tôi đã tạo một người dùng SQL Server.

1> create login gouser with password='g0us3r';
2> go
1> create user gouser for login gouser;
2> go

Tiếp theo, tôi đã tải xuống và cài đặt Microsoft SQL Server Management Studio. Đây là một tiện ích khác với Trình quản lý cấu hình SQL Server. Bằng cách sử dụng này, tôi đã thực hiện hai việc:(1) bật Xác thực máy chủ SQL cũng như Xác thực Windows và (2) cung cấp các quyền cần thiết cho người dùng SQL Server mới của tôi gouser . Tiện ích này cũng cung cấp một giao diện người dùng đẹp để duyệt qua SQL Server và các cơ sở dữ liệu khác nhau của nó.

Đảm bảo rằng người dùng SQL mà bạn tạo có đủ quyền để có thể sử dụng nó để kết nối với SQL Server và tạo cơ sở dữ liệu.

Một số cân nhắc khi sử dụng xác thực Windows

Sau khi nghiên cứu thêm, tôi thấy rằng tôi thực sự có thể sử dụng Xác thực Windows tuy nhiên phải cung cấp id người dùng hoàn toàn đủ điều kiện và mật khẩu của nó. Đối với môi trường sử dụng Active Directory với tên miền "AD", id người dùng đủ điều kiện sẽ là "AD \ userid" và đối với máy chủ cục bộ sẽ là "\ userid". Tôi vẫn đang nghiên cứu về việc có thể tự động sử dụng thông tin đăng nhập của người dùng hiện đang đăng nhập.

Sau khi vẫn nghiên cứu thêm và tìm sự hỗ trợ từ các nhà phát triển trình điều khiển Go, Xác thực Windows với hiện tại sẽ có thể thực hiện được nếu sql.Open() không bao gồm thông tin người dùng có nghĩa là "id người dùng =; mật khẩu =;" không nên được chỉ định.

Tuy nhiên, hình thức Xác thực Windows tự động này đối với người dùng hiện tại chỉ được phép nếu phiên bản SQL Server đang sử dụng Kerberos với Tên chính của Dịch vụ (SPN) hợp lệ. Nếu bạn thực hiện khởi động lại phiên bản SQL Server của mình và bạn thấy nhật ký sau trong tệp ERRORLOG của mình, thì SQL Server không thể khởi chạy bằng Kerberos.

2016-08-23 18:32:16.77 Máy chủ Thư viện Giao diện Mạng Máy chủ SQL không thể đăng ký Tên chính của Dịch vụ (SPN) cho Dịch vụ Máy chủ SQL. Lỗi:0x54b, trạng thái:3. Việc không đăng ký SPN có thể khiến xác thực tích hợp trở lại NTLM thay vì Kerberos. Đây là một thông báo cung cấp thông tin. Chỉ cần thực hiện thêm hành động nếu xác thực Kerberos được yêu cầu bởi chính sách xác thực.

Xem thêm Cách đảm bảo rằng bạn đang sử dụng xác thực Kerberos khi tạo kết nối từ xa đến một phiên bản của SQL Server 2005 cung cấp một số thông tin bổ sung cũng như sử dụng setspn lệnh để khắc phục sự cố.

Xem thêm Thư viện giao diện mạng SQL không thể đăng ký SPN.

Giới thiệu về Xác thực Windows đáng tin cậy (Cập nhật theo yêu cầu từ @Richard bởi @xpt)

Xác thực Windows đang đăng nhập vào SQL Server bằng thông tin đăng nhập Windows mà không chỉ định id người dùng và mật khẩu. Đây được gọi là kết nối đáng tin cậy cho sqlcmd hoặc ODBC; hoặc được gọi là Đăng nhập một lần cho go-mssqldb Gói trình điều khiển đi.

Từ go-mssqldb readme của github,

"id người dùng" - nhập id người dùng Xác thực Máy chủ SQL hoặc id người dùng Xác thực Windows ở định dạng DOMAIN \ Người dùng. Trên Windows, nếu userid trống hoặc bị thiếu Đăng nhập một lần được sử dụng.

Vì vậy, tôi đã thử hai cách sau với SQL Server 2008 R2 của mình và cả hai đều hoạt động tốt:

condb, errdb := sql.Open("mssql", "server=MyServer;user id=;password=DONTCARE;")
condb, errdb := sql.Open("mssql", "server=MyServer;user id=;password=;")

Lưu ý rằng việc sử dụng server =localhost sẽ không thành công, vì điều quan trọng là phải có tên máy chủ lưu trữ chính xác, từ tên đó, trình điều khiển đang xây dựng Tên chính của dịch vụ kerberos SQL Server (SPN) và tên đó phải khớp với SQL Server. Tôi đã sử dụng Tên chính của dịch vụ (SPN) phù hợp với thử nghiệm của mình để nó hoạt động.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chuyển đổi ‘datetimeoffset’ thành ‘date’ trong SQL Server (Ví dụ T-SQL)

  2. Hiểu Nhóm theo Mệnh đề trong SQL Server - Hướng dẫn SQL Server / TSQL Phần 130

  3. Liệu một Công việc Máy chủ SQL có bỏ qua một lần chạy theo lịch trình nếu nó đang chạy không?

  4. Cài đặt Ubuntu 18.04 cho SQL Server 2019 trên máy ảo bằng VMware Workstation

  5. Hiệu suất máy chủ SQL TOP IO Truy vấn -2