Як падлічыць колькасць сапраўдных значэнняў у базе дадзеных, дзе слупок змяшчае «Q1»

У мяне ёсць табліца ў базе дадзеных доступу, якая мае слупкі Q1-Easy Q1-Med і Q1-Hard. Для абранага карыстальніка, мне трэба падлічыць колькасць слупкоў, якія ўтрымліваюць праўдзівае значэнне.

будзе працаваць гэты SQL заяву? ці ёсць больш элегантны спосаб зрабіць гэта?

string Q1Query = "SELECT COUNT from tbl_Results WHERE ([Q1-Easy] OR [Q1-Med] OR [Q1-Hard] && [Username]) = + selectedUsername + "'";

Я ведаю толькі самыя асновы ў SQL, і я працую ў C# .NET

0
Бакавы (але важна) Заўвага: Выкарыстанне параметризованных запытаў. Ня забудаваць SQL з канкатэнацыі.
дададзена аўтар Chris Farmer, крыніца
Бакавы (але важна) Заўвага: Выкарыстанне параметризованных запытаў. Ня забудаваць SQL з канкатэнацыі.
дададзена аўтар Chris Farmer, крыніца
І мае прыярытэт над АБО, так што вы, верагодна, хочаце, каб групаваць ([Q1-Easy] АБО [Q1-Med] АБО [Q1-Hard]) пункт у свае ўласныя дужкі.
дададзена аўтар Chris Farmer, крыніца
І мае прыярытэт над АБО, так што вы, верагодна, хочаце, каб групаваць ([Q1-Easy] АБО [Q1-Med] АБО [Q1-Hard]) пункт у свае ўласныя дужкі.
дададзена аўтар Chris Farmer, крыніца
што з'яўляецца ўразлівай SQL радок для пачатку.
дададзена аўтар Woot4Moo, крыніца
Ах, арэхі. Мой адказ не збіраецца, каб дапамагчы з сумаваннем колькасці ісцін. Але не глядзець на параметрызацыі запытаў.
дададзена аўтар ThatBlairGuy, крыніца
Ах, арэхі. Мой адказ не збіраецца, каб дапамагчы з сумаваннем колькасці ісцін. Але не глядзець на параметрызацыі запытаў.
дададзена аўтар ThatBlairGuy, крыніца
Вы павінны быць больш канкрэтнымі аб тым, што вы спрабуеце зрабіць. Ваша пытанне кажа: «падлічваць колькасць слупкоў, якія ўтрымліваюць сапраўднае значэнне», але ваш запыт будзе вяртаць колькасць радкоў, якія маюць па крайняй меры адзін слупок з сапраўдным значэннем. Што вы збіраецеся для? Напрыклад, калі слупкі Easy, Med, і Hard ўсе маюць праўдзівае значэнне для дадзенай радкі вы хочаце, што лічыцца як 1 або 3? Звярніце ўвагу на каментар Woot4Moo, а таксама, нават пасля таго, як вы атрымаеце SQL сам прыбіты падыход вы карыстаецеся небяспечна. Google "SQL Injection"
дададзена аўтар dazedandconfused, крыніца
Вы павінны быць больш канкрэтнымі аб тым, што вы спрабуеце зрабіць. Ваша пытанне кажа: «падлічваць колькасць слупкоў, якія ўтрымліваюць сапраўднае значэнне», але ваш запыт будзе вяртаць колькасць радкоў, якія маюць па крайняй меры адзін слупок з сапраўдным значэннем. Што вы збіраецеся для? Напрыклад, калі слупкі Easy, Med, і Hard ўсе маюць праўдзівае значэнне для дадзенай радкі вы хочаце, што лічыцца як 1 або 3? Звярніце ўвагу на каментар Woot4Moo, а таксама, нават пасля таго, як вы атрымаеце SQL сам прыбіты падыход вы карыстаецеся небяспечна. Google "SQL Injection"
дададзена аўтар dazedandconfused, крыніца
прабачце за бязладдзе, я хацеў бы, каб вярнуць значэнне 3, калі ўсё 3 калонкі маюць праўдзівае значэнне для гэтага карыстальніка. Ці два, калі толькі 2 праўдзівыя. Я не шукаю для радкоў, ён павінен быць слупкамі. дзякуй, L
дададзена аўтар LHammy, крыніца
прабачце за бязладдзе, я хацеў бы, каб вярнуць значэнне 3, калі ўсё 3 калонкі маюць праўдзівае значэнне для гэтага карыстальніка. Ці два, калі толькі 2 праўдзівыя. Я не шукаю для радкоў, ён павінен быць слупкамі. дзякуй, L
дададзена аўтар LHammy, крыніца

8 адказы

Ваш запыт не занадта далёка ад ісціны. Што вы хочаце,

string Q1Query = "SELECT COUNT(*) from tbl_Results WHERE ([Q1-Easy] = 'Y' OR [Q1-Med] = 'Y' OR [Q1-Hard] = 'Y') && [Username] = '" + selectedUsername + "'";

(Калі выказаць здагадку, што «праўдзівае значэнне» з'яўляецца «Y».)

Гэта, як гаворыцца, ўкладанне вашага SQL ў C# і будаваць яго з дапамогай канкатэнацыі гэта дрэнная ідэя. Гэта дапускае магчымасць зламысных уваходаў, такіх як selectedUsername , які змяшчае значэнне «Бобі", DROP TABLE студэнтаў ». Значна лепш практыка параметризовать запыт і хай код базы дадзеных змясціць у імя карыстальніка або яшчэ лепш, паставіць увесь запыт у зберажоную працэдуру.

Каб пазбегнуць ін'екцыі SQL vulnernability, вы хочаце змяніць запыт на нешта накшталт гэтага:

string Q1Query = "SELECT COUNT(*) from tbl_Results WHERE ([Q1-Easy] = 'Y' OR [Q1-Med] = 'Y' OR [Q1-Hard] = 'Y') && [Username] = '@username'";

(Звярніце ўвагу, што выдаленне канкатэнацыі для карыстальніка.)

І тады вы на самой справе запусціць яго з чымсьці накшталт гэтага:

SqlCommand cmd = new SqlCommand(Q1Query);
cmd.Parameters.Add("@username", selectedUsername);
SqlDataReader reader = cmd.ExecuteReader();
1
дададзена
Пасля таго, як ваш каментар з растлумачэннем аб неабходнасці колькасці слупкоў, я зразумеў, што мой запыт не будзе працаваць. Адказ ад @dazedandconfused гэта шлях. Але ў любым выпадку, вы павінны абсалютна пазбягаць стварэння запытаў SQL ў кодзе сярэдняга ўзроўню. Параметризованных з'яўляецца <�б> шмат бяспечней.
дададзена аўтар ThatBlairGuy, крыніца
атрымаў гэты код працуе з базай дадзеных MS Access з дапамогай: Con.Open (); cmd.Parameters.Add ( "@ Імя карыстальніка", OleDbType.VarChar) .Value = selectedStudent; cmd.ExecuteNonQuery (); INT вынік = ((INT) cmd.ExecuteScalar ()); Радок resultString = result.ToString (); MessageBox.Show (resultString); Con.Close (); Потым зразумеў, што я атрымаў адказ 1, калі я павінен быў атрымаць 3. Гэта слупкі, якія я хачу, каб падлічыць замест радкоў. Аператар СЛУЧАЙ робіць тое, што я хачу, але я выкарыстоўваю MS Access
дададзена аўтар LHammy, крыніца
дзякуй, я дам гэта паспрабаваць
дададзена аўтар LHammy, крыніца

Ваш запыт не занадта далёка ад ісціны. Што вы хочаце,

string Q1Query = "SELECT COUNT(*) from tbl_Results WHERE ([Q1-Easy] = 'Y' OR [Q1-Med] = 'Y' OR [Q1-Hard] = 'Y') && [Username] = '" + selectedUsername + "'";

(Калі выказаць здагадку, што «праўдзівае значэнне» з'яўляецца «Y».)

Гэта, як гаворыцца, ўкладанне вашага SQL ў C# і будаваць яго з дапамогай канкатэнацыі гэта дрэнная ідэя. Гэта дапускае магчымасць зламысных уваходаў, такіх як selectedUsername , які змяшчае значэнне «Бобі", DROP TABLE студэнтаў ». Значна лепш практыка параметризовать запыт і хай код базы дадзеных змясціць у імя карыстальніка або яшчэ лепш, паставіць увесь запыт у зберажоную працэдуру.

Каб пазбегнуць ін'екцыі SQL vulnernability, вы хочаце змяніць запыт на нешта накшталт гэтага:

string Q1Query = "SELECT COUNT(*) from tbl_Results WHERE ([Q1-Easy] = 'Y' OR [Q1-Med] = 'Y' OR [Q1-Hard] = 'Y') && [Username] = '@username'";

(Звярніце ўвагу, што выдаленне канкатэнацыі для карыстальніка.)

І тады вы на самой справе запусціць яго з чымсьці накшталт гэтага:

SqlCommand cmd = new SqlCommand(Q1Query);
cmd.Parameters.Add("@username", selectedUsername);
SqlDataReader reader = cmd.ExecuteReader();
1
дададзена
Пасля таго, як ваш каментар з растлумачэннем аб неабходнасці колькасці слупкоў, я зразумеў, што мой запыт не будзе працаваць. Адказ ад @dazedandconfused гэта шлях. Але ў любым выпадку, вы павінны абсалютна пазбягаць стварэння запытаў SQL ў кодзе сярэдняга ўзроўню. Параметризованных з'яўляецца <�б> шмат бяспечней.
дададзена аўтар ThatBlairGuy, крыніца
атрымаў гэты код працуе з базай дадзеных MS Access з дапамогай: Con.Open (); cmd.Parameters.Add ( "@ Імя карыстальніка", OleDbType.VarChar) .Value = selectedStudent; cmd.ExecuteNonQuery (); INT вынік = ((INT) cmd.ExecuteScalar ()); Радок resultString = result.ToString (); MessageBox.Show (resultString); Con.Close (); Потым зразумеў, што я атрымаў адказ 1, калі я павінен быў атрымаць 3. Гэта слупкі, якія я хачу, каб падлічыць замест радкоў. Аператар СЛУЧАЙ робіць тое, што я хачу, але я выкарыстоўваю MS Access
дададзена аўтар LHammy, крыніца
дзякуй, я дам гэта паспрабаваць
дададзена аўтар LHammy, крыніца

Добра, калі вы хочаце, каб падлічыць колькасць сапраўдных слупкоў вы збіраецеся трэба нешта накшталт наступнага. Звярніце ўвагу, што я мяркую, што значэнне а «Y» азначае, праўду ... калі вы выкарыстоўваеце бітаў слупкі, якія вы павінны будзеце ўнесці нязначныя змены. Я таксама мяркую, што вы знаходзіцеся на SQL Server, калі гэта не так, гэты сінтаксіс не можа працаваць для вас.

   SELECT 
      CASE Q1-Easy WHEN 'Y' THEN 1 ELSE 0 END + 
      CASE Q1-Med  WHEN 'Y' THEN 1 ELSE 0 END + 
      CASE Q1-Hard WHEN 'Y' THEN 1 ELSE 0 END AS TrueCount
   FROM tbl_Results
   WHERE ([Username] = @username)

Для MS Access, гэта будзе нешта накшталт наступнага (неправераныя) ...

   SELECT 
      IIF([Q1-Easy] = 'Y', 1, 0) + 
      IIF([Q1-Med] = 'Y', 1, 0) +
      IIF([Q1-Hard] = 'Y', 1, 0) AS TrueCount
   FROM tbl_Results
   WHERE ([Username] = @username)
1
дададзена
Aha! У мяне быў ментальны блок на CASE . Ваш адказ дае запыт яму трэба, мой забяспечвае бяспечны спосаб дадаць параметрызацыі.
дададзена аўтар ThatBlairGuy, крыніца
Адрэдагаваны, каб дадаць сінтаксіс MS Access. У мяне няма доступу да наяўнага на дадзены момант, так што, магчыма, спатрэбіцца трохі падправіць, але павінен атрымаць вас у футбольным полі.
дададзена аўтар dazedandconfused, крыніца
дзякуй dazedandconfused, гэта менавіта тое, што я спрабую зрабіць, але гэта з базай дадзеных доступу
дададзена аўтар LHammy, крыніца
дзякуй так шмат dazedandconfused - гэта працуе для мяне менавіта так, як вы паказваеце тут! Цалкам ацаніць хуткія і карысныя адказы ад членаў перапаўнення стэка, яго вялікага сайта. Дзякуй зноў!
дададзена аўтар LHammy, крыніца

Добра, калі вы хочаце, каб падлічыць колькасць сапраўдных слупкоў вы збіраецеся трэба нешта накшталт наступнага. Звярніце ўвагу, што я мяркую, што значэнне а «Y» азначае, праўду ... калі вы выкарыстоўваеце бітаў слупкі, якія вы павінны будзеце ўнесці нязначныя змены. Я таксама мяркую, што вы знаходзіцеся на SQL Server, калі гэта не так, гэты сінтаксіс не можа працаваць для вас.

   SELECT 
      CASE Q1-Easy WHEN 'Y' THEN 1 ELSE 0 END + 
      CASE Q1-Med  WHEN 'Y' THEN 1 ELSE 0 END + 
      CASE Q1-Hard WHEN 'Y' THEN 1 ELSE 0 END AS TrueCount
   FROM tbl_Results
   WHERE ([Username] = @username)

Для MS Access, гэта будзе нешта накшталт наступнага (неправераныя) ...

   SELECT 
      IIF([Q1-Easy] = 'Y', 1, 0) + 
      IIF([Q1-Med] = 'Y', 1, 0) +
      IIF([Q1-Hard] = 'Y', 1, 0) AS TrueCount
   FROM tbl_Results
   WHERE ([Username] = @username)
1
дададзена
Aha! У мяне быў ментальны блок на CASE . Ваш адказ дае запыт яму трэба, мой забяспечвае бяспечны спосаб дадаць параметрызацыі.
дададзена аўтар ThatBlairGuy, крыніца
Адрэдагаваны, каб дадаць сінтаксіс MS Access. У мяне няма доступу да наяўнага на дадзены момант, так што, магчыма, спатрэбіцца трохі падправіць, але павінен атрымаць вас у футбольным полі.
дададзена аўтар dazedandconfused, крыніца
дзякуй dazedandconfused, гэта менавіта тое, што я спрабую зрабіць, але гэта з базай дадзеных доступу
дададзена аўтар LHammy, крыніца
дзякуй так шмат dazedandconfused - гэта працуе для мяне менавіта так, як вы паказваеце тут! Цалкам ацаніць хуткія і карысныя адказы ад членаў перапаўнення стэка, яго вялікага сайта. Дзякуй зноў!
дададзена аўтар LHammy, крыніца

Дужкі няправільна ў запыце. Гэта форма ў тым, што вы хочаце:

SELECT COUNT(*)
from tbl_Results
WHERE ([Q1-Easy] = 'TRUE' OR [Q1-Med] = 'TRUE' OR [Q1-Hard] = 'TRUE') AND
      ([Username] = + selectedUsername)

Я не ведаю, як «ісціна» прадстаўлена ў вашых дадзеных, таму значэнне можа адрознівацца.

0
дададзена

Дужкі няправільна ў запыце. Гэта форма ў тым, што вы хочаце:

SELECT COUNT(*)
from tbl_Results
WHERE ([Q1-Easy] = 'TRUE' OR [Q1-Med] = 'TRUE' OR [Q1-Hard] = 'TRUE') AND
      ([Username] = + selectedUsername)

Я не ведаю, як «ісціна» прадстаўлена ў вашых дадзеных, таму значэнне можа адрознівацца.

0
дададзена

Амаль такі ж, як у вас на з нязначнымі, але важнымі выпраўленнямі:

string Q1Query = "SELECT [UserName], COUNT(*) as ToTalTrueQuestions 
FROM tbl_Results WHERE ([Q1-Easy] OR [Q1-Med] OR [Q1-Hard]) 
AND [Username] = '" +    selectedUsername + "'";

The difference first is I include the name of the user to associate with the count, second the count has an alias, third your use of parenthesis is wrong I put the closing parenthesis ")" after the [Q1-Hard] not after [Username], fourth I use AND which is for SQL instead of && which is for C# and finally there is a single quote after "=", that is "= '" should be the correct one.

0
дададзена

Амаль такі ж, як у вас на з нязначнымі, але важнымі выпраўленнямі:

string Q1Query = "SELECT [UserName], COUNT(*) as ToTalTrueQuestions 
FROM tbl_Results WHERE ([Q1-Easy] OR [Q1-Med] OR [Q1-Hard]) 
AND [Username] = '" +    selectedUsername + "'";

The difference first is I include the name of the user to associate with the count, second the count has an alias, third your use of parenthesis is wrong I put the closing parenthesis ")" after the [Q1-Hard] not after [Username], fourth I use AND which is for SQL instead of && which is for C# and finally there is a single quote after "=", that is "= '" should be the correct one.

0
дададзена