मैं SQL सर्वर एक्सप्रेस 2008 का उपयोग करके एक साधारण डेमो गो भाषा डेटाबेस प्रोग्राम पर काम करने के अपने अनुभव को साझा करना चाहता हूं। मेरा मानना है कि सीखे गए निम्नलिखित पाठ 2008 और बाद के किसी भी SQL सर्वर संस्करण पर लागू होंगे।
मेरा SQL सर्वर एक्सप्रेस पहले default
. के साथ स्थापित किया गया था उदाहरण के बजाय named
उदाहरण। यह विंडोज प्रमाणीकरण का उपयोग करने के लिए भी स्थापित किया गया था। मेरे द्वारा किए जाने वाले अन्य विकास कार्यों के लिए इन दोनों सेटिंग्स की आवश्यकता थी। दूसरा काम जो मैं करता हूं, उसी पीसी पर SQL सर्वर एक्सप्रेस का उपयोग स्थानीय डेटाबेस इंजन के रूप में एप्लिकेशन के रूप में करता है। मैं अपने गो एप्लिकेशन में SQL सर्वर के साथ विंडोज प्रमाणीकरण का उपयोग करने में सक्षम होने की उम्मीद कर रहा था।
स्थानीय SQL सर्वर और गो के साथ उपयोग करने के लिए एक ड्राइवर और एक छोटा सा नमूना कार्यक्रम की तलाश में, यह प्रश्न मेरी खोज में आया। मैंने कुछ अतिरिक्त जानकारी और एक नमूना कार्यक्रम जोड़ने के बारे में सोचा ताकि दूसरों को आरंभ करने और अपनी गलतियों से सीखने में मदद मिल सके। मुझे यह लेख 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")
}
SQL सर्वर सेटिंग्स में आवश्यक परिवर्तन किए जाने के बाद उपरोक्त एप्लिकेशन को पहली बार चलाने पर, यह निम्न आउटपुट उत्पन्न करेगा। चूंकि पहली बार प्रोग्राम चलाने पर डेटाबेस मौजूद नहीं होता है, आप त्रुटि संदेश मुद्रित देखेंगे। हालाँकि बाद के समय में इसे चलाने पर डेटाबेस मौजूद रहेगा और डेटाबेस के गिराए जाने पर त्रुटि संदेश आउटपुट नहीं होगा।
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
SQL सर्वर ड्राइवर पैकेज स्थापित करना
पहली चीज जो मुझे करनी थी वह थी डेटाबेस ड्राइवर पैकेज ढूंढना जो SQL सर्वर के साथ काम करेगा। कई स्टैकओवरफ्लो पोस्टिंग अनुशंसित github.com/denisenkom/go-mssqldb
इसलिए इसका उपयोग किया जाता है।
github.com/denisenkom/go-mssqldb
. का उपयोग करने के लिए पैकेज मुझे पहले इसे जीथब रिपॉजिटरी से पुनः प्राप्त करना था go get github.com/denisenkom/go-mssqldb
का उपयोग करके Git Shell
. चलाकर बनाई गई कमांड शेल विंडो से ।
Git Shell
जीथब शेल है जिसे गिट स्थापित करने के हिस्से के रूप में स्थापित किया गया है। मैंने पाया कि मुझे go get
the चलाना था Git Shell
में कमांड करें go
. के क्रम में git
. खोजने के लिए कमांड एप्लिकेशन और जीथब रिपॉजिटरी तक पहुंचें। जब मैंने go get
. चलाने की कोशिश की एक सामान्य कमांड शेल से कमांड मैंने एक त्रुटि संदेश देखा जो दर्शाता है कि 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
SQL सर्वर के लिए TCP कनेक्शन सक्षम करना
कुछ खोज के बाद मुझे कई अलग-अलग साइटें मिलीं, जो सभी ने संकेत दिया कि त्रुटि का मतलब है कि मेरा SQL सर्वर इंस्टेंस टीसीपी/आईपी के लिए कॉन्फ़िगर नहीं किया गया था। विभिन्न पोस्टिंग से संकेत मिलता है कि मुझे Sql Server Configuration Manager
का उपयोग करने की आवश्यकता है टीसीपी/आईपी सक्षम करने के लिए।
मैंने जो खोजा वह यह है कि वास्तव में दो स्थान हैं जहां टीसीपी/आईपी को सक्षम करने की आवश्यकता है। एक था Client Protocols
और वह वास्तव में पहले से ही सक्षम था। हालांकि दूसरा था Protocols for MSSQLSERVER
और उसमें एक टीसीपी/आईपी अक्षम कर दिया गया था। इसलिए मैंने Protocols for MSSQLSERVER
. में TCP/IP को सक्षम किया अनुभाग, फिर नियंत्रण कक्ष से प्रशासनिक उपकरण की सेवा उपयोगिता का उपयोग करके SQL सर्वर सेवा को पुनरारंभ किया।
हालाँकि मुझे sql.Open()
. का उपयोग करने के बाद भी किसी भी प्रकार की क्वेरी में समस्या आ रही थी . मैं एप्लिकेशन आउटपुट देख रहा था जो निम्न में से कुछ भिन्नता थी। त्रुटि संदेश वही था, हालांकि जब फ़ंक्शन कॉल में त्रुटियां एक रन से अगले रन में बदल सकती थीं। मैंने sql.Open()
. में निर्दिष्ट कनेक्शन स्ट्रिंग को बदलने का प्रयास किया विभिन्न त्रुटि संदेशों के अलावा कोई परिणाम नहीं मिला।
starting app
Error Exec db: create db - driver: bad connection
Error Exec db: create table - driver: bad connection
ending app
आगे देखने पर मुझे यह नोट जीथब रिपोजिटरी में मिला:
<ब्लॉकक्वॉट>ज्ञात मुद्दे
SQL Server 2008 और 2008 R2 इंजन जब SSL एन्क्रिप्शन अक्षम नहीं है, तो लॉगिन रिकॉर्ड को हैंडल नहीं कर सकता है। SQL Server 2008 R2 समस्या को ठीक करने के लिए, SQL Server 2008 R2 सर्विस पैक 2 स्थापित करें। SQL Server 2008 समस्या को ठीक करने के लिए, SQL Server 2008 SP3 के लिए Microsoft SQL Server 2008 सर्विस पैक 3 और संचयी अद्यतन पैकेज 3 स्थापित करें। अधिक जानकारी:http://support.microsoft.com/kb/2653857
इसलिए मैंने उन अद्यतनों को डाउनलोड किया जिन्हें मैंने वास्तव में कभी स्थापित नहीं किया था। डाउनलोड की प्रतीक्षा करते हुए, मैंने और अधिक देखा और पाया कि वास्तविक SQL सर्वर निष्पादन योग्य फ़ोल्डर के साथ Log
है। फ़ाइलों की एक श्रृंखला युक्त फ़ोल्डर ERRORLOG
, ERRORLOG.1
, आदि.
SQL सर्वर लॉग इंगित करते हैं कि SQL सर्वर उपयोगकर्ता की आवश्यकता है
ERRORLOG
में देख रहे हैं फ़ाइल मुझे निम्नलिखित लॉग के साथ SQL सर्वर का एक त्रुटि लॉग मिला जो पहेली का अगला भाग प्रदान करता है:
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]
मुझे तब एहसास हुआ कि गो SQL सर्वर ड्राइवर Windows प्रमाणीकरण का उपयोग नहीं कर रहा था, बल्कि SQL सर्वर प्रमाणीकरण का उपयोग कर रहा था। मैंने एक खाली user id=
. निर्दिष्ट करके Windows प्रमाणीकरण का उपयोग करने का प्रयास किया था हालांकि यह काम नहीं लग रहा था। तो sqlcmd
. का उपयोग करके उपयोगिता, मैंने एक SQL सर्वर उपयोगकर्ता बनाया है।
1> create login gouser with password='g0us3r';
2> go
1> create user gouser for login gouser;
2> go
इसके बाद मैंने Microsoft SQL सर्वर प्रबंधन स्टूडियो को डाउनलोड और स्थापित किया। यह SQL सर्वर कॉन्फ़िगरेशन प्रबंधक से भिन्न उपयोगिता है। इसका उपयोग करके मैंने दो काम किए:(1) SQL सर्वर प्रमाणीकरण के साथ-साथ Windows प्रमाणीकरण चालू किया और (2) मेरे नए SQL सर्वर उपयोगकर्ता gouser
के लिए आवश्यक अनुमतियां प्रदान की . इस उपयोगिता ने SQL सर्वर और इसके विभिन्न डेटाबेस ब्राउज़ करने के लिए एक अच्छा उपयोगकर्ता इंटरफ़ेस भी प्रदान किया।
सुनिश्चित करें कि आपके द्वारा बनाए गए SQL उपयोगकर्ता के पास पर्याप्त अनुमतियाँ हैं ताकि इसका उपयोग SQL सर्वर से कनेक्ट करने और डेटाबेस बनाने के लिए किया जा सके।
Windows प्रमाणीकरण का उपयोग करने के लिए कुछ विचार
आगे के शोध के बाद मैंने पाया कि मैं वास्तव में विंडोज प्रमाणीकरण का उपयोग कर सकता हूं, हालांकि पूरी तरह से योग्य यूजर आईडी और उसका पासवर्ड प्रदान किया जाना चाहिए। "AD" के डोमेन नाम के साथ सक्रिय निर्देशिका का उपयोग करने वाले वातावरण के लिए पूरी तरह से योग्य उपयोगकर्ता आईडी "AD\userid" होगी और स्थानीय होस्ट के लिए "\userid" होगी। मैं अभी भी वर्तमान में लॉग इन उपयोगकर्ता के क्रेडेंशियल्स का स्वचालित रूप से उपयोग करने में सक्षम होने पर शोध कर रहा हूं।
अभी और शोध के बाद और गो ड्राइवर डेवलपर्स से सहायता प्राप्त करने के बाद, विंडोज प्रमाणीकरण वर्तमान के साथ संभव होना चाहिए यदि sql.Open()
उपयोगकर्ता जानकारी शामिल नहीं है जिसका अर्थ है "उपयोगकर्ता आईडी =पासवर्ड =;" निर्दिष्ट नहीं किया जाना चाहिए।
हालाँकि वर्तमान उपयोगकर्ता के विरुद्ध स्वचालित Windows प्रमाणीकरण के इस रूप की अनुमति केवल तभी दी जाती है जब SQL सर्वर इंस्टेंस एक मान्य सेवा प्रधान नाम (SPN) के साथ Kerberos का उपयोग कर रहा हो। यदि आप SQL सर्वर के अपने इंस्टेंस पर पुनरारंभ करते हैं और आप अपनी ERRORLOG फ़ाइल में निम्न लॉग देखते हैं, तो SQL सर्वर Kerberos के साथ प्रारंभ करने में सक्षम नहीं था।
<ब्लॉकक्वॉट>2016-08-23 18:32:16.77 सर्वर SQL सर्वर नेटवर्क इंटरफ़ेस लाइब्रेरी SQL Serverservice के लिए सेवा प्रधान नाम (SPN) पंजीकृत नहीं कर सका। त्रुटि:0x54b, स्थिति:3. किसी SPN को पंजीकृत करने में विफलता के कारण एकीकृत प्रमाणीकरण Kerberos के बजाय NTLM में वापस आ सकता है। यह एक सूचनात्मक संदेश है। आगे की कार्रवाई केवल तभी आवश्यक है जब प्रमाणीकरण नीतियों के लिए Kerberos प्रमाणीकरण आवश्यक हो।
यह भी देखें कि कैसे सुनिश्चित करें कि आप केर्बेरोज प्रमाणीकरण का उपयोग कर रहे हैं जब आप SQL सर्वर 2005 की एक आवृत्ति के लिए एक दूरस्थ कनेक्शन बनाते हैं जो setspn
का उपयोग करके कुछ अतिरिक्त जानकारी प्रदान करता है। समस्या को ठीक करने का आदेश।
यह भी देखें SQL नेटवर्क इंटरफ़ेस लाइब्रेरी SPN को पंजीकृत करने में असमर्थ थी।
विश्वसनीय Windows प्रमाणीकरण के बारे में (@Richard द्वारा @xpt द्वारा अनुरोध के अनुसार अपडेट किया गया)
विंडोज प्रमाणीकरण एक यूजर आईडी और पासवर्ड निर्दिष्ट किए बिना विंडोज क्रेडेंशियल के साथ SQL सर्वर में लॉग इन कर रहा है। इसे sqlcmd
. के लिए विश्वसनीय कनेक्शन कहा जाता है या ODBC
; या go-mssqldb
. के लिए सिंगल-साइन-ऑन कहा जाता है गो ड्राइवर पैकेज।
go-mssqldb
. से जीथब में रीडमी,
"यूजर आईडी" - DOMAIN\User फॉर्मेट में SQL सर्वर ऑथेंटिकेशन यूजर आईडी या WindowsAuthentication यूजर आईडी दर्ज करें। विंडोज़ पर, यदि उपयोगकर्ता आईडी खाली है या अनुपलब्ध है तो सिंगल-साइन-ऑन का उपयोग किया जाता है।
इसलिए मैंने अपने 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=;")
ध्यान दें कि सर्वर =लोकलहोस्ट का उपयोग करना विफल हो जाएगा, क्योंकि सही होस्ट नाम होना महत्वपूर्ण है, उस नाम से ड्राइवर SQL सर्वर kerberos सर्विस प्रिंसिपल नेम (SPN) बना रहा है और वह नाम SQL सर्वर से मेल खाना चाहिए। मैंने अपने परीक्षण के साथ एक उचित सेवा प्रधान नाम (एसपीएन) का उपयोग किया है, इसलिए यह काम करता है।