Database Access using ADO.NET

હવે એ objects ખરું કામ કરે છે: connection ખોલો, DataReader થી FestConnect ના events વાંચવા SELECT ચલાવો, અને registration સાચવવા INSERT ચલાવો, હંમેશા parameters સાથે, વપરાશકારે ભરેલું લખાણ SQL ના string માં ચોંટાડીને કદી નહીં.

11 min read · 9 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


Theory

ખરેખરનું વાંચવું અને લખવું

ADO.NET નાં પાત્રો તમે ઓળખો છો; હવે એમને FestConnect નાં રોજિંદાં બે કામે લગાડો: page પર બતાવવા માટે events ની list વાંચવી, અને વિદ્યાર્થી નોંધાય ત્યારે નવું registration લખવું.

વાંચવા માટે Command નું ExecuteReader અને DataReader વપરાય છે; લખવા માટે ExecuteNonQuery વપરાય છે. રસ્તામાં database ના code ની સૌથી અગત્યની એક ટેવ પણ આવે છે: વપરાશકાર પાસેથી આવેલી કોઈ પણ કિંમત માટે parameters વાપરો. આ પાઠ બંને ક્રિયાઓ બતાવે છે અને એ ટેવ કેમ બાંધછોડ વગરની છે તે પણ.

Follow along

Connected વાચનની ઢબ

  1. Connection ખોલો Connection string સાથે SqlConnection બનાવો અને એને ખોલો (સૌથી સારું તો using block ની અંદર, જે એને આપોઆપ બંધ કરે છે).
  2. Command બનાવો તમારું SELECT વિધાન ધરાવતું SqlCommand, જે connection સાથે બંધાયેલું હોય.
  3. ExecuteReader Rows ને વહેતી આપતું SqlDataReader મેળવવા cmd.ExecuteReader() બોલાવો.
  4. Read() સાથે આંટા મારો while (reader.Read()) એક સમયે એક row આગળ વધારે છે; columns ને નામથી વાંચો.
  5. બંધ કરો કામ પતે ત્યારે using block connection બંધ કરી દે છે, ભૂલ આવે તો પણ.

Practical

FestConnect ના events વાંચવા

using (var conn = new SqlConnection(connectionString))
{
    var cmd = new SqlCommand("SELECT Name, EventDate FROM Events", conn);
    conn.Open();

    SqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())          // true while there is another row
    {
        string name = reader["Name"].ToString();
        // ... add name to a list, or bind it to a control
    }
}   // connection closed automatically here

Theory

લખવું: ExecuteNonQuery

Database બદલવા માટે, એટલે કે registration insert કરવા, વિગત update કરવા કે row delete કરવા, તમે Command નું ExecuteNonQuery વાપરો છો. નામનો અર્થ છે 'એવો command ચલાવો જે query નથી (SELECT નથી)'. એ વિધાન ચલાવે છે અને કેટલી rows પર અસર થઈ તે સંખ્યા પાછી આપે છે.

એટલે એક registration ઉમેરતું એક INSERT 1 પાછું આપે છે. લખાણ સફળ થયું કે નહીં એની ખાતરી કરવા આ પાછી મળતી કિંમત કામની છે: તમે એક row insert કરવાની ધારણા રાખી હોય અને ExecuteNonQuery 1 પાછું આપે, તો એ સફળ થયું એમ સમજાય.

Practical

Registration ને parameters સાથે સાચવવું

using (var conn = new SqlConnection(connectionString))
{
    // @name and @eventId are PLACEHOLDERS, not the actual values
    var cmd = new SqlCommand(
        "INSERT INTO Registrations (StudentName, EventId) VALUES (@name, @eventId)",
        conn);

    // Supply the user's values as parameters (safe)
    cmd.Parameters.AddWithValue("@name", txtName.Text);
    cmd.Parameters.AddWithValue("@eventId", selectedEventId);

    conn.Open();
    int rows = cmd.ExecuteNonQuery();   // returns 1 for one inserted row
    lblStatus.Text = rows == 1 ? "Registered!" : "Something went wrong.";
}

Watch out

વપરાશકારે ભરેલું લખાણ SQL માં કદી ચોંટાડશો નહીં

Database ના code ની સૌથી ખતરનાક એક ભૂલ એટલે વપરાશકારે ભરેલા લખાણને જોડીને SQL બનાવવો, જેમ કે "... VALUES ('" + txtName.Text + "')". મુલાકાતી એ ખાનામાં પોતાનું SQL લખી શકે અને તમારી query એ ચલાવી નાખે, અને એ હુમલાને SQL injection કહે છે (DBMS માં અને PHP ના unit માં તમે એને મળી ચૂક્યા છો).

એને બદલે હંમેશા parameters વાપરો (@name, જે cmd.Parameters દ્વારા ઉમેરાય છે). પછી ADO.NET વપરાશકારનું લખાણ કડક રીતે ફક્ત કિંમત તરીકે મોકલે છે, ચાલી શકે એવા SQL તરીકે કદી નહીં, એટલે injection થઈ જ ન શકે. વપરાશકારે આપેલી દરેક કિંમતને, દર વખતે, parameter બનાવો. અને connection હંમેશા બંધ કરો (using block એની ખાતરી આપે છે).

Quiz

એક નવી registration ની row સાચવવા તમે INSERT ચલાવો છો. તમે કઈ method બોલાવો છો, અને એ શું પાછું આપે છે?

  1. ExecuteReader, જે insert થયેલી row ને DataReader તરીકે પાછી આપે છે
  2. ExecuteNonQuery, જે INSERT ચલાવે છે અને અસર પામેલી rows ની સંખ્યા પાછી આપે છે (એક insert માટે 1)
  3. ExecuteScalar, જે આખું Registrations table પાછું આપે છે
  4. DataBind, જે row insert કરે છે અને page તાજું કરે છે
Show the answer

ExecuteNonQuery, જે INSERT ચલાવે છે અને અસર પામેલી rows ની સંખ્યા પાછી આપે છે (એક insert માટે 1)

INSERT rows પાછી આપવાને બદલે data બદલે છે, એટલે તમે ExecuteNonQuery બોલાવો છો, જે વિધાન ચલાવે છે અને અસર પામેલી rows ની સંખ્યા પાછી આપે છે: એક insert થયેલા registration માટે એ 1 છે. વિકલ્પ A ખોટો છે: ExecuteReader એ rows વહેતી પાછી આપતી SELECT queries માટે છે, INSERT માટે નહીં. વિકલ્પ C ખોટો છે: ExecuteScalar એક જ કિંમત (એક ખાનું, જેમ કે COUNT) પાછી આપે છે, આખું table નહીં, અને એ insert માટેની method પણ નથી. વિકલ્પ D ખોટો છે: DataBind એ UI ની method છે જે data ને control પર render કરે છે; એ database ને અડતી નથી. વાંચવા માટે ExecuteReader; બદલવા માટે (insert, update, delete) ExecuteNonQuery, જે કેટલી rows બદલાઈ તે પણ કહે છે.

Think first

Parameters SQL injection ને બરાબર કઈ રીતે અટકાવે છે?

બંને છેવટે વપરાશકારનું લખાણ જ વાપરે છે, તો પણ "'" + txtName.Text + "'" જોખમી હોય અને @name સલામત હોય એવું શા માટે? વિચારીને પછી tap કરો.

Show the answer

કારણ કે parameters વપરાશકારના લખાણને હંમેશા DATA તરીકે રાખે છે, command ના માળખાના ભાગ તરીકે કદી નહીં. તમે જોડાણ કરો ત્યારે વપરાશકારે ટાઇપ કરેલું લખાણ SQL ના string નો જ ભાગ બની જાય છે, એટલે એ કોઈ અવતરણચિહ્ન પછી પોતાનું SQL લખે તો database એને commands તરીકે વાંચીને ચલાવે છે, અને એ જ injection છે. Parameter સાથે તમે database ને બે અલગ વસ્તુ મોકલો છો: placeholder (@name) વાળું નિશ્ચિત SQL નું ઢાંચું, અને એની સાથે બાંધવાની કિંમત. Database પહેલાં ઢાંચું compile કરે છે અને એનું માળખું નક્કી કરી લે છે, અને પછી જ કિંમતને કડક રીતે data તરીકે એમાં ગોઠવે છે, એટલે કે સંઘરવા માટેનું સાદું લખાણ, જેને SQL તરીકે ફરી કદી વાંચવામાં આવતું નથી. એટલે વપરાશકાર ગમે તે ટાઇપ કરે, અવતરણચિહ્નો, અર્ધવિરામો, કે આખું DROP TABLE વિધાન, એ ફક્ત લખાણ તરીકે જ સંઘરાય, ચાલે નહીં. આ PHP નાં prepared statements જેવું જ રક્ષણ છે: query ના માળખાને એની કિંમતોથી અલગ કરો, અને injection અશક્ય બની જાય. માળખું અને data અલગ અલગ મુસાફરી કરવાં જોઈએ; ADO.NET એમને અલગ રાખવા parameters વાપરે છે.

Summary

Key takeaways

  • Connection, Command અને ExecuteReader થી વાંચો: DataReader મેળવો અને reader.Read() rows માં આગળ વધારે ત્યાં સુધી આંટા મારો.
  • Data બદલવા (insert, update, delete) ExecuteNonQuery વાપરો, જે અસર પામેલી rows ની સંખ્યા પાછી આપે છે: એક insert માટે 1.
  • ExecuteScalar એક જ કિંમત પાછી આપે છે (જેમ કે COUNT); ExecuteReader rows પાછી આપે છે; ExecuteNonQuery ગણતરી પાછી આપે છે.
  • વપરાશકારે ભરેલા લખાણ માટે હંમેશા parameter વાળી queries વાપરો (cmd.Parameters દ્વારા @name); એને SQL માં કદી જોડશો નહીં.
  • જોડાણ SQL injection ને છૂટ આપે છે; parameters વપરાશકારનું લખાણ કડક રીતે data તરીકે મોકલે છે, એટલે એ SQL તરીકે કદી ચાલી શકતું નથી.
  • Connection હંમેશા બંધ કરો; using block એ કામ આપોઆપ કરે છે, ભૂલ આવે તો પણ.
  • યાદ રાખવાની કડી: વાંચવા ExecuteReader, બદલવા ExecuteNonQuery, અને વપરાશકારની દરેક કિંમતને parameter બનાવો.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Database Access and Client-Server Communications

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati