Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Pergi dengan driver SQL Server tidak dapat terhubung dengan sukses, login gagal

Saya ingin berbagi pengalaman saya mengerjakan demo sederhana program basis data bahasa Go menggunakan SQL Server Express 2008. Saya percaya bahwa pelajaran berikut ini akan berlaku untuk semua versi SQL Server dari tahun 2008 dan yang lebih baru.

SQL Server Express saya sebelumnya diinstal dengan default contoh daripada named contoh. Itu juga diinstal untuk menggunakan Otentikasi Windows. Kedua pengaturan ini diperlukan oleh pekerjaan pengembangan lain yang saya lakukan. Pekerjaan lain yang saya lakukan menggunakan SQL Server Express pada PC yang sama dengan aplikasi sebagai mesin database lokal. Saya berharap dapat menggunakan Otentikasi Windows dengan SQL Server di aplikasi Go saya.

Mencari driver dan program sampel kecil untuk digunakan dengan SQL Server lokal dan Go, pertanyaan ini muncul dalam pencarian saya. Saya berpikir untuk menambahkan sedikit informasi tambahan dan contoh program untuk membantu orang lain memulai dan belajar dari kesalahan saya. Saya juga menemukan artikel ini GoLang dan MSSQL Databases:An Example berguna terutama setelah membuat kesalahan yang cukup sehingga saya lebih memahaminya.

Versi terakhir dari program pengujian saya adalah sebagai berikut:

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

Pertama kali aplikasi di atas dijalankan setelah perubahan yang diperlukan untuk pengaturan SQL Server dibuat, itu akan menghasilkan output berikut. Karena database tidak ada saat pertama kali program dijalankan, Anda akan melihat pesan kesalahan tercetak. Namun kali berikutnya dijalankan, database akan ada dan pesan kesalahan saat database dijatuhkan tidak akan ditampilkan.

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

Memasang paket Driver SQL Server

Hal pertama yang harus saya lakukan adalah menemukan paket driver database yang akan bekerja dengan SQL Server. Beberapa posting stackoverflow direkomendasikan github.com/denisenkom/go-mssqldb jadi itulah yang digunakan.

Untuk menggunakan github.com/denisenkom/go-mssqldb paket saya harus terlebih dahulu mengambilnya dari repositori github menggunakan go get github.com/denisenkom/go-mssqldb dari jendela shell perintah yang dibuat dengan menjalankan Git Shell .

Git Shell adalah shell github yang diinstal sebagai bagian dari menginstal Git. Saya menemukan bahwa saya harus menjalankan go get perintah di Git Shell agar go perintah untuk menemukan git aplikasi dan mengakses repositori github. Ketika saya mencoba menjalankan go get perintah dari shell perintah normal Saya melihat pesan kesalahan yang menunjukkan bahwa git perintah tidak dapat ditemukan.

Setelah menginstal go-mssqldb paket Saya dapat menjalankan aplikasi sampel saya dan terus mengalami kesalahan runtime dari Open() . Output dari aplikasi saya adalah sebagai berikut:

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

Mengaktifkan koneksi TCP untuk SQL Server

Setelah beberapa pencarian saya menemukan sejumlah situs berbeda yang semuanya menunjukkan bahwa kesalahan berarti bahwa contoh SQL Server saya tidak dikonfigurasi untuk TCP/IP. Berbagai posting menunjukkan saya perlu menggunakan Sql Server Configuration Manager untuk mengaktifkan TCP/IP.

Apa yang saya temukan adalah bahwa sebenarnya ada dua tempat di mana TCP/IP perlu diaktifkan. Salah satunya adalah Client Protocols dan itu memang sudah diaktifkan. Namun yang lainnya adalah Protocols for MSSQLSERVER dan dalam satu TCP/IP dinonaktifkan. Jadi saya mengaktifkan TCP/IP di Protocols for MSSQLSERVER bagian, kemudian restart layanan SQL Server menggunakan utilitas Layanan dari Alat Administratif dari Panel Kontrol.

Namun saya masih mengalami masalah dengan segala jenis kueri setelah menggunakan sql.Open() . Saya melihat keluaran aplikasi yang merupakan beberapa variasi berikut. Pesan kesalahannya sama namun ketika panggilan fungsi memiliki kesalahan dapat berubah dari satu proses ke proses berikutnya. Saya mencoba mengubah string koneksi yang ditentukan dalam sql.Open() tanpa hasil selain pesan kesalahan yang berbeda.

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

Melihat-lihat lebih jauh, saya menemukan catatan ini di repositori github:

Masalah Umum

Mesin SQL Server 2008 dan 2008 R2 tidak dapat menangani catatan login saat enkripsi SSL tidak dinonaktifkan. Untuk memperbaiki masalah SQL Server 2008 R2, instal SQL Server 2008 R2 Paket Layanan 2. Untuk memperbaiki masalah SQL Server 2008, instal Microsoft SQL Server 2008 Paket Layanan 3 dan paket pembaruan kumulatif 3 untuk SQL Server 2008 SP3. Informasi lebih lanjut:http://support.microsoft.com/kb/2653857

Jadi saya mengunduh pembaruan yang sebenarnya tidak pernah saya instal. Sambil menunggu unduhan, saya melihat-lihat lebih lanjut dan menemukan folder yang berisi SQL Server yang sebenarnya dapat dieksekusi bersama dengan Log folder yang berisi serangkaian file ERRORLOG , ERRORLOG.1 , dll.

Log SQL Server menunjukkan pengguna SQL Server diperlukan

Melihat di ERRORLOG file Saya menemukan log kesalahan SQL Server dengan log berikut yang memberikan potongan teka-teki berikutnya:

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]

Saya kemudian menyadari bahwa driver Go SQL Server tidak menggunakan Otentikasi Windows tetapi menggunakan Otentikasi SQL Server. Saya telah mencoba menggunakan Otentikasi Windows dengan menentukan user id= empty yang kosong namun itu sepertinya tidak berhasil. Jadi gunakan sqlcmd utilitas, saya membuat pengguna SQL Server.

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

Selanjutnya saya mengunduh dan menginstal Microsoft SQL Server Management Studio. Ini adalah utilitas yang berbeda dari Manajer Konfigurasi SQL Server. Dengan menggunakan ini, saya melakukan dua hal:(1) mengaktifkan Otentikasi SQL Server serta Otentikasi Windows dan (2) memberikan izin yang diperlukan untuk pengguna SQL Server baru saya gouser . Utilitas ini juga menyediakan antarmuka pengguna yang bagus untuk menjelajahi SQL Server dan berbagai databasenya.

Pastikan pengguna SQL yang Anda buat memiliki izin yang memadai sehingga dapat digunakan untuk terhubung ke SQL Server dan membuat database.

Beberapa Pertimbangan untuk Menggunakan Otentikasi Windows

Setelah penelitian lebih lanjut saya menemukan bahwa saya benar-benar dapat menggunakan Otentikasi Windows namun id pengguna yang sepenuhnya memenuhi syarat dan kata sandinya harus diberikan. Untuk lingkungan yang menggunakan Active Directory dengan nama domain "AD" id pengguna yang memenuhi syarat adalah "AD\userid" dan untuk host lokal adalah "\userid". Saya masih meneliti untuk dapat menggunakan kredensial pengguna yang saat ini masuk secara otomatis.

Setelah penelitian lebih lanjut dan menemukan bantuan dari pengembang driver Go, Otentikasi Windows dengan saat ini harus dimungkinkan jika sql.Open() tidak menyertakan informasi pengguna yang berarti "id pengguna =; kata sandi =;" tidak harus ditentukan.

Namun bentuk Otentikasi Windows otomatis terhadap pengguna saat ini hanya diperbolehkan jika contoh SQL Server menggunakan Kerberos dengan Nama Prinsip Layanan (SPN) yang valid. Jika Anda melakukan restart pada instance SQL Server dan Anda melihat log berikut di file ERRORLOG Anda, SQL Server tidak dapat menginisialisasi dengan Kerberos.

23-08-2016 18:32:16.77 Server Pustaka Antarmuka Jaringan SQL Server tidak dapat mendaftarkan Nama Utama Layanan (SPN) untuk layanan SQL Server. Galat:0x54b, status:3. Kegagalan untuk mendaftarkan SPN dapat menyebabkan autentikasi terintegrasi kembali ke NTLM alih-alih Kerberos. Ini adalah pesan informasi. Tindakan lebih lanjut hanya diperlukan jika otentikasi Kerberos diperlukan oleh kebijakan otentikasi.

Lihat juga Cara memastikan bahwa Anda menggunakan otentikasi Kerberos saat Anda membuat sambungan jarak jauh ke instance SQL Server 2005 yang menyediakan beberapa informasi tambahan juga menggunakan setspn perintah untuk memperbaiki masalah.

Lihat juga Pustaka Antarmuka Jaringan SQL tidak dapat mendaftarkan SPN.

Tentang Otentikasi Windows Tepercaya (Diperbarui sesuai permintaan dari @Richard oleh @xpt)

Otentikasi Windows masuk ke SQL Server dengan kredensial Windows tanpa menentukan id pengguna dan kata sandi. Ini disebut koneksi tepercaya untuk sqlcmd atau ODBC; atau disebut Single-Sign-On untuk go-mssqldb Pergi paket driver.

Dari go-mssqldb 's readme di github,

"user id" - masukkan id pengguna SQL Server Authentication atau id pengguna WindowsAuthentication dalam format DOMAIN\User. Di Windows, jika userid kosong atau tidak ada Single-Sign-On digunakan.

Jadi saya mencoba dua cara berikut dengan SQL Server 2008 R2 saya dan keduanya berfungsi dengan baik:

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

Perhatikan bahwa menggunakan server=localhost akan gagal, karena penting untuk memiliki nama host yang benar, dari nama itu driver sedang membangun Nama Utama Layanan (SPN) SQL Server kerberos dan nama itu harus cocok dengan SQL Server. Saya menggunakan Nama Prinsip Layanan (SPN) yang tepat dengan pengujian saya sehingga berfungsi.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kesalahan MSSQL 'Penyedia yang mendasari gagal saat Buka'

  2. PILIH BERBEDA pada satu kolom

  3. SQL Server - gabungkan baris ke dalam daftar yang dipisahkan koma

  4. Memformat Nomor Telepon di SQL Server (T-SQL)

  5. Jenis Kursor SQL Server - Kursor KEYSET | Tutorial SQL Server / Tutorial TSQL