"db.Exec ()" का उपयोग क्यों करें:
यह सच है कि आप db.Exec
. का उपयोग कर सकते हैं और db.Query
एक ही एसक्यूएल स्टेटमेंट को निष्पादित करने के लिए एक दूसरे के लिए हालांकि दो विधियां विभिन्न प्रकार के परिणाम लौटाती हैं। यदि ड्राइवर द्वारा कार्यान्वित किया जाता है तो परिणाम db.Exec
. से वापस आ जाता है आपको बता सकता है कि क्वेरी से कितनी पंक्तियां प्रभावित हुईं, जबकि db.Query
इसके बजाय रो ऑब्जेक्ट लौटाएगा।
उदाहरण के लिए मान लें कि आप एक DELETE
निष्पादित करना चाहते हैं कथन और आप जानना चाहते हैं कि इसके द्वारा कितनी पंक्तियाँ हटाई गईं। आप इसे या तो उचित तरीके से कर सकते हैं:
res, err := db.Exec(`DELETE FROM my_table WHERE expires_at = $1`, time.Now())
if err != nil {
panic(err)
}
numDeleted, err := res.RowsAffected()
if err != nil {
panic(err)
}
print(numDeleted)
या अधिक क्रियात्मक और वस्तुनिष्ठ रूप से महंगा तरीका:
rows, err := db.Query(`DELETE FROM my_table WHERE expires_at = $1 RETURNING *`, time.Now())
if err != nil {
panic(err)
}
defer rows.Close()
var numDelete int
for rows.Next() {
numDeleted += 1
}
if err := rows.Err(); err != nil {
panic(err)
}
print(numDeleted)
पोस्टग्रेज़ CTE के संयोजन के साथ आप ऐसा करने का एक तीसरा तरीका है, SELECT COUNT
, db.QueryRow
और row.Scan
लेकिन मुझे नहीं लगता कि यह दिखाने के लिए एक उदाहरण आवश्यक है कि db.Exec
की तुलना में एक दृष्टिकोण कितना अनुचित होगा। ।
db.Exec
. का उपयोग करने का एक अन्य कारण db.Query
. से अधिक तब होता है जब आपको दिए गए परिणाम की परवाह नहीं होती है, जब आपको केवल क्वेरी को निष्पादित करना होता है और जांचना होता है कि कोई त्रुटि हुई है या नहीं। ऐसी स्थिति में आप यह कर सकते हैं:
if _, err := db.Exec(`<my_sql_query>`); err != nil {
panic(err)
}
दूसरी ओर, आप ऐसा नहीं कर सकते (आप कर सकते हैं लेकिन आपको नहीं करना चाहिए):
if _, err := db.Query(`<my_sql_query>`); err != nil {
panic(err)
}
ऐसा करने से, थोड़ी देर के बाद, आपका प्रोग्राम एक त्रुटि से घबरा जाएगा जो too many connections open
जैसा कुछ कहती है . ऐसा इसलिए है क्योंकि आप लौटाए गए db.Rows
. को छोड़ रहे हैं पहले अनिवार्य किए बिना मान Close
उस पर कॉल करें, और इसलिए आप अंत में खुले कनेक्शनों की संख्या में वृद्धि करते हैं और अंततः सर्वर की सीमा तक पहुंच जाते हैं।
"या गोलंग में तैयार किए गए कथन?":
मुझे नहीं लगता कि आपने जिस पुस्तक का हवाला दिया है वह सही है। कम से कम मेरे लिए ऐसा लगता है कि db.Query
. है या नहीं कॉल हर बार आपके द्वारा उपयोग किए जा रहे ड्राइवर पर निर्भर होने पर एक नया तैयार स्टेटमेंट बनाता है।
उदाहरण के लिए देखें queryDC
. के ये दो खंड (db.Query
. द्वारा बुलाया गया एक निर्यात न की गई विधि ):बिना तैयार बयान के और तैयार बयान के साथ।
भले ही किताब सही हो या नहीं एक db.Stmt
db.Query
. द्वारा बनाया गया होगा, जब तक कि कुछ आंतरिक कैशिंग नहीं चल रही हो, आपके द्वारा लौटाई गई Rows
को बंद करने के बाद फेंक दिया जाएगा वस्तु। यदि आप इसके बजाय मैन्युअल रूप से db.Prepare
. पर कॉल करते हैं और फिर कैश करें और लौटाए गए db.Stmt
. का पुन:उपयोग करें आप संभावित रूप से उन प्रश्नों के प्रदर्शन में सुधार कर सकते हैं जिन्हें अक्सर निष्पादित करने की आवश्यकता होती है।
यह समझने के लिए कि प्रदर्शन को अनुकूलित करने के लिए तैयार किए गए कथन का उपयोग कैसे किया जा सकता है, आप आधिकारिक दस्तावेज़ीकरण पर एक नज़र डाल सकते हैं:https://www.postgresql.org/docs/current/static/sql-prepare.html