מה הבעיה בתחביר הזה ?

TechMen

New member
מה הבעיה בתחביר הזה ?

cmd.CommandText="UPDATE CompTav SET "+ @"TeorBohen='"+RbTeorBohen.Text +"' "+ @"TechName='"+tbTech.Text +"' "+ @"TipolDate='"+dt1.ToShortDateString()+"' "+ @"TipolStartHour='"+dt2.ToShortTimeString()+"' "+ @"Statos='"+CbStatos.Text +", "+ "where CartisNum=" +lbCartisNum.Text ;
 

TechMen

New member
תדביק אותו לקובץ טקסט ..

ותראה אותו כמו שצריך .... למקרה ואתה לא יודע Ctrl + Shift בצד השמאלי של המקלדת יסדרו לך את זה כמו שצריך :))
 

TechMen

New member
כן אבל זה לא עובד

ניסתי להריץ את זה ויש בעיות עם זה אולי בגלל שאני על אקסס ולא על SQL אני בודק את זה עם יש לך הצעות אני אשמח
 

gilad g

New member
מספיק ../images/Emo88.gif

המשך הדיון הזה נמחק, בשל הרמה הנמוכה שאליו הוא התדרדר. זאת פעם ראשונה (ואני מקווה שגם אחרונה) שאני חוסם מישהו על ריבים כאלו. אני לא רוצה לראות יותר בפורום אמירות ברמה כזאת נמוכה.
 

orenphp

New member
קוד מיושר לשמאל + ....

cmd.CommandText="UPDATE CompTav SET "+ @"TeorBohen='"+RbTeorBohen.Text +"' "+ @"TechName='"+tbTech.Text +"' "+ @"TipolDate='"+dt1.ToShortDateString()+"' "+ @"TipolStartHour='"+dt2.ToShortTimeString()+"' "+ @"Statos='"+CbStatos.Text +", "+ "where CartisNum=" +lbCartisNum.Text ;​
השגיאה שראיתי היא שאתה לא שם "," בין השדות בSET שלך (חוץ מהאחרון, דווקא שם כן שמת וזה לא אמור להיות שם). הסינטקס אמור להיות:
update table_name set column_name='value', column_name1='value1' where column_name2='somevalue'​
חשוב מאוד: תשתמש בBind Parameters בשביל השאילתא, אחרת אני אוכל די בקלות להכניס לך קוד זדוני שיבצע לך דברים לא הכי נחמדים בDB. (sql injection) על שימוש בפרמטרים באובייקט Command שלך אתה יכול לחפש בmsdn או לקרוא מאמר בנושא: http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson06.aspx לגבי מה זה sql injection - חיפוש קצר בגוגל יתן לך שפע של מאמרים. בהצלחה. ותעשו לי טובה, אל תריבו על שטויות, בזבוז מיותר של חיי מקלדת.
 

Zeliran

New member
מישהו נורמלי פה?

זה כבר באמת מתחיל להרגיז, אתה בא לפה ומתחיל להגדיר את עצמך כאיש חביב שלא מפריע לו להתחיל לחפש דברים כל כך קטנונים כמו יישור לשמאל כדי להתחיל לפתוח בהודעות כדוגמת "בוא שב לי עליו" שמזכירים לי את הגנון, אבל לפחות אומר תודה שמישהו באמת בא ועוזר לך, שאני לפחות במקומו, כלל לא הייתי עושה את זה אחרי שאני רואה עם איזו גישה את מגיע לכאן לא נראה לך? אף אחד באמת לא מכריח אותך להישאר כאן, רוצה להישאר? בכיף, רק לא חייב להגיע עם גישה מתנשאת של "לא, אני לא מוכן ליישר את הקוד לשמאל, אבל מעדיף לפתוח שירשור שלם על כך שאתם מפגרים" באמת לא מתאים
 

Justin Angel

New member
בקשר ל-Sql injection

לא תמיד ניתן להשתמש ב-Bind variables. למשל במצב של פרמטרים אופציונאליים, לא ניתן לבנות SP או שאילתא רגילה שתתאים למצב כאלו. ההגנה צריכה להיות ברמת הקלט מהמשתמש ולא רק בשיטות העבודה בתוך הקוד.
 

orenphp

New member
גם כאן אפשר להשתמש בbind variables.

ברגע שאני אוסיף לשאילתא חלק אני אדאג להוסיף גם את ה"פרמטר" שלו. אם יש לך דוגמא ספציפית שנתקלת בה, אשמח אם תביא אותה לכאן וננסה לראות איך משתמשים גם בה בbind variables.
 

Justin Angel

New member
דוגמה תיאורטית

יש לי טבלה בעלת 30 שדות, עליה אני רוצה להריץ חיפוש לפי דף חיפוש מהמשתמש. המשתמש יכול למלות בין 1 ל 30 שדות. איך בדיוק תמנע פה הרכבה דינמית של שאילתת SQL? את ההרכבה הדינמית צריך לעשות בשאילתא דינמית רגילה. ולאחר שהורכב ה-CommandText יש להצהיר על ה-Bind variables הנכונים. לא ניתן לעשות SP או כל דבר סטטי אחר לחיפוש דינמי על טבלה שלמה. מבחינה רעיונית זה גם לא מסתדר להשתמש בכלים סטטים לסוגיה דינמית.
 

gilad g

New member
פרמטרים אופציונליים ל-SP

יכולה להיות אופציה. אני לא בטוח בקשר לתמיכה בהם ב-SqlSrv, אבל ב-oracle אפשר להגדיר פרמטרים אופציונליים, ולבנות את השאילתה דינאמית בתוך ה-SP
גם אם אין תמיכה בהם, אפשר תמיד להעביר NULL.
 

Justin Angel

New member
אפשר הכל

אבל בדקת את זמן הריצה של זה? בדוגמה למעלה של 30 משתנים אופציונאליים עדיף כבר לקחת נשק ולירות בשרת, במקום לענות אותו. למעשה מה שאני מכיר כתמיכה של אורקל במשתנים אופציונאליים זה שהשאילתא מכילה את כל 30 השדות. ככה שכך נראית הSP:
Select... where myVar=:myVar​
אם נשלח ערך ל-myVar, אז תתבצע השוואה. אם לא נשלח ערך, אז יוכנס ערך גלובלי. ע"ע myVar=%. וכשיש לך 30 משתנים זה רצח לשרת. או שיש אופציה יותר טובה באורקל שאני לא מודע לה?
 

gilad g

New member
אפשר פשוט לשלוח NULL,

ולבנות את השאילתה דינמית (לפתוח אותה עם Cusors - באורקל זה לא סיפור כמו ב-SQLSRV).
 

orenphp

New member
דוגמא כזאת דווקא הייתי פותר בc#

ולא בSP כמו שחברי המלומד גלעד הציע. הסיבה היא פשוטה - אין להכניס לוגיקה כזאת לתוך הSP, הSP צריך לדעת לבצע פעולה פשוטה עד כמה שניתן. כלל אצבע שלי לגבי SP: לא להכניס לוגיקה של אפליקציה לSP (שוב, SP צריך להיות פשוט). (כמובן שזה ניתן לויכוח, אבל כל אחד מתכנת ע"פ שיקוליו) לכן, הייתי מחליט על איזה פורמט מסוים, נניח: 1. במידה ואני מקבל פרמטר סטרינגי ריק (כלומר "") - אני לא מוסיף אותו לשאילתא. 2. במידה ואני מקבל ערך מספרי שאני יודע שלא יכול להיות 0 (טבלת קודים - כלומר תן לי את כל הפריטים של המשתמש X (כאשר אני יודע שX!=0)) אז אני לא אוסיף אותו לשאילתא. כך אני אקבע לעצמי מספר חוקים ולפי הפרמטרים שנשלחו אני אדע איך לבנות את השאילתא ואיך לצרף את הparameters (בכל if של בדיקה, במידה ואני אמור להוסיף את התנאי לשאילתא אני אוסיף גם את הparameter לCommand). אני הייתי בונה את כל הCommandText שלי בc# בDAL component, מריץ את השאילתא ומנתח את התוצאות.
 

gilad g

New member
נשמע טוב,

גם כשבונים את ה-SP יש סכנה ל-SQL Injection. כמובן שצריך לעשות ניתוח יותר מעמיק של ביצועים, ולא להחליט ככה סתם מי מהיר יותר (ה-DB או האפליקציה). הערותיי: 1. למה לקבל פרמטר סטרינג ריק / אפס? method overloading ופרמטרים אופציונליים ב-#C זאת אפשרות יותר טובה ונקיה
2. לפעמים שדות יכולים לקבל 0. אז הייתי מציע להשתמש ב-INullable (ולחכות ל-C# 2.0 בשביל <Nullable<T), או לשלוח object, אם בא לך לעשות boxing.
 

orenphp

New member
תשובות להערות.

(איחדתי את התשובות מאחר וראיתי קשר בינהן) כאן לדעתי אין צורך בoverloading, אתה רוצה לבצע חיפוש ע"פ חתך מסויים בטופס. אני כנראה אף פעם לא אשלח Null לBL(ומשם לDAL) כי אני לא רוצה לעבוד קשה ולבצע בaspx שלי בדיקה - אם השדה שלי Name.Text=="" אז שלח null כפרמטר, אלא אני רוצה לשלוח ישירות את Name.Text ולתת לBL+DAL "לשבור את הראש" (טיפול כפול, בDAL + aspx לדעתי זה סתם error prone(טיפלתי בDAL אבל שכחתי בaspx...) וטיפול כפול בלוגיקה יחידה). לכן נראה לי שoverloading מיותר, אלא אם כן אני מאפשר checkboxes בטופס שיצביעו "האם לחתוך תוצאות על פי שדה זה". אני חושב שלשלוח Null זה טיפה לא תואם מציאות (+נוח לתוכניתן, אבל שוב, רק במידה ואני לא מאפשר "האם לחתוך על פי שדה זה") ואני אסביר - סה"כ יש לנו כאן טופס שמכיל שדות שאנחנו רוצים לחתוך לפיהם. במידה והמשתמש לא הזין ערך לשדה "שם" למשל, כנראה שהוא פשוט לא רצה לחתוך לפי זה ולא תן לי את כל השמות הריקים (כמובן, תלוי אפליקציה, אבל יש להניח שברוב המקרים זה יתפוס). אם יש לי Drop-down-lists אז בד"כ הם יהיו מלאים בערכים מטבלת קודים (למשל במסך משתמשים, מצב אפשרי הוא שיהיה לי איזה DDL של "ערים" - תן לי את כל המשתמשים מעיר X), יתכן שאני ארצה להוסיף option ריק כדי לא לחתוך תוצאות לפי זה (תן לי את כל המשתמשים, אבל אל תתייחס למיקומם הגאוגרפי) - זה מקרה קלאסי שהייתי מזין בoption הריק את הvalue=0. ואז כמובן יכלתי לפי נתון זה לא להוסיף את אותו תנאי(+join) לשאילתא. לכן בחרתי בשני חוקים שציינתי בהודעתי הקודמת, אבל כפי שאמרתי - יש המון מקרים, המון אפשרויות, אבל תמיד יש להשתמש בbind variables - זה טוב לביצועים וטוב לאבטחה. מקווה שזה היה סיכום ממצה.
 
למעלה