SQL problemi

Salam .Belə bir qurluşlu cədvəlim var. CREATE TABLE mehsul( ID VARCHAR(10) DEFAULT DEFAULT '0', mehsul VARCHAR(15) DEFAULT '0', PRIMARY KEY (İD) ) Proqramı Servletdə (JAVA) yazmışam.Koddan xırda bir hissəni sizə göstərim. "DELETE FROM mehsul WHERE ID='"+ms+"'"; "INSERT INTO mehsul VALUSE('"+id+"',"'+ms+"')"; Kod i.l'yir lakin b'zi hallarda belə bir səff veririr. 3159085-Duplicate entry 3159085-121 for key 1 Burada 121-məhsulun İD-sidir.Yəniki birinci DELETE əmri bəzi hallarda yerinə yetrilmir.Əgər kimsə bu haqda nəsə bilirsə kömək etməyiniznizi xaiş edərdim.

Verilmiş cavablar və yazılan şərhlər (12 cavab var)

kamilh (2011-09-27 13:59:21)
Cox sağ ol Ramin müəllim.....SQL injection təhlükəsi var.bəs bu təhlükəni aradan necə qaldıra bilərəm.?

Ramin Orucov (2011-09-18 14:00:49)
INSERT ... ON DUPLICATE KEY UPDATE ilə bağlı dokumentasiya http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html

Ramin Orucov (2011-09-18 13:57:03)
Bunu üçün Oracle-da MERGE əmri var, amma gördüyüm qədər MySQL bunu dəstəkləmir. MySQL üçün belə bir variant var: [code]INSERT ... ON DUPLICATE KEY UPDATE[/code] Sizin misal üçün belə olacaq: [code]INSERT INTO mehsul (id,mehsul) VALUES ('1001','121') ON DUPLICATE KEY UPDATE mehsul='121'; [/code] Sizin cədvəl və koda baxanda 2 sualım yarandı: 1.İD sütunu niyə varchar kimi təyin etmisiniz? İçərisində rəqəmlər saxlayırsınızsa, int tipli və auto increment edin, daha yaxşı olar. 2.SQL sorğularında niyə parameter istifadə etmirsiniz? Sizin bu sorğularınız qeyri optimaldır + SQL injection təhlükəsi var. [code] “DELETE FROM mehsul WHERE ID=’”+ms+”‘”; [/code] JDBC-də PreparedStatement istifadə etməklə hər 2 problemin qarşısını almaq olar: [code] String sql = "DELETE FROM mehsul WHERE ID=?"; PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1, "1001"); ps.executeQuery(); [/code]

ruslan (2011-06-27 01:53:13)
update table set value='key' where value='key' update sorgusu beledir cenab..

kamilh (2011-06-23 22:20:16)
Hörmətli admin cavabınıza görə çox sağ olun.Bəs mən bir tranzaksiya ilə necə edə bilərəmki əgər varsa UPDATE olsun yoxsa İNSERT olsun? Yoxsa bunun üçündə bir SQL sorğu yazmalıyam?Minnətdaram sizə....

admin (2011-06-23 17:22:34)
Yuxarıdakı sualıma cavab vermədiniz. Update-lə bağlı. Və məncə 99% faiz dublicate entry səhvin nəticəsi odur. Siz delete, insert əvəzinə update-dən istifadə edin. Delete və insert olanda iki tranzaksiya olur, paralel başqa istifadəçi də bu əməliyyatı edəndə 2 tranzaksiya da ordan gəlir, əgər bu 2x2=4 sorğuda növbəlilik pozularsa(və eyni anda hər iki user müraciət edəndə olur bu) o halda bir user delete etməmiş o biri insert etmək istəyir eyni İD-ni, və dublicate error verir. Bunun ən effektiv həll yolu insert, delete-i ləğv edib update query-sindən istifadə etməkdir.

kamilh (2011-06-23 17:09:31)
Hərf səhfidir.max_connections =100 birdəki onu qeyd edimki hər bir bazaya müraciət bitəndəən sonra baza ilə əlaqə kəsilir.yeniki connectionlar açıq qalmır.nəisə..........

admin (2011-06-23 01:32:03)
Sizin sayt shared hostinqdə yerləşir ya öz serverinizdə? Shared hostinqlərdə mysql max_connections məhdudiyyəti var və online istifadəçilərin bazaya paralel müraciətlərinin(davamlı connectionların) sayı müəyyən həddə çatanda belə şeylər olur. Odur ki ola bilər ki problem məhz bundadır. Çünki deyirsiniz ki məhz problem çox user olanda olur. Siz hostinq administratoru ilə əlaqə saxlayıb max_connections nəyə bərabərdir öyrənin. Müstəqil Linux serverdə isə bu parametri /etc/my.cnf faylından dəyişmək olur. (Başqa serverlərdə də my.cnf faylıdır, amma fərqli papkalarda yerləşir). Bir də ki niyə delete,insert edirsiniz ki, birbaşa update edə bilməzsiniz? İki əvəzinə bir sorğu. P.S. Bu sualda ilk əvvəldən query-də VALUES əvəzinə VALUSE yazmısınız, ümid edirəm ki bu sadəcə burda hərf səhvi ilə elə düşüb, saytda belə olsa ümumiyyətlə işləməz :)

kamilh (2011-06-22 22:57:53)
Salam hörmətli admin.İlk önçə cavablarınıza görə çox sağ olun. [code] CREATE TABLE mehsul( ID VARCHAR(10) DEFAULT DEFAULT ’0′, mehsul VARCHAR(15) DEFAULT ’0′, PRIMARY KEY (İD) ) [/code] cədvəlin qurluşu belədir.və [code] DELETE FROM mehsul WHERE ID='1001' INSERT INTO mehsul VALUSE('1001','858') [/code] Lakin proqram yüksək dərəcədə yüklənənda yəniki eyni zamanda 20-25 user işlədəndə [code] DELETE FROM mehsul WHERE ID='1001' [/code] bloklanır yəniki locked olur bunun səbəini bilmək istərdim.

admin (2011-06-21 14:26:33)
Bu texniki problem deyil, kod problemidir. Fikrimcə səhv də məhz Sənan yazan variantdır. Siz eyni primary key-i təkrar daxil etməyə cəhd göstərirsiniz. Loru desək primaru key bir dəfə istifadə üçün yarayır ancaq, sonra onu silsəniz belə, yenə də istifadə edə bilməsziniz. Məsələn İD-yə auto_increment verəndən sonra ən son İD=10-dursa onu silin. Belədə ən son İD 9 olmuş olacaq. Və yeni bir sətir insert edin, görəcəksiniz ki İD=11 oldu, baxmayaraq ki, 10 yoxdur.

kamilh (2011-06-20 23:22:06)
Salam.Bilrəmki iki eyni şey təkrar ola bilməz.Məhz buna görə İNSERT-dən öncə DELET -dən istifadə edirem.işləyir.Lakin bəzi hallarda DELET komandası işləmir.sadəcə mən bunun səbəbini bilmək istərdim.Bu hal userlərin sayı gün ərzində 1000-dən çox olanda baş verir.Ola bilərmiki Server artıq yüklənir? yoxsa MYSQL-in konfiqrasiyonu faylında userlərə məhduduiyət qoyulur?

Sənan (2011-06-20 14:39:51)
Kamil. Sen İD ye primary key qoymusan. Bu o demekdir ki, eyni şeyi tekrar İD sutununa daxil ede bilmezsen. İNSERT edende birinci sutun İD, ikinci mehsuldu. yaxsi olarki İNSERT mehsul (İD, mehsul) VALUES ('asdas', 'asd') kimi yazasan. Onda hansi sutuna ne yazildigi aydin goruner. Bir sozle mehsul cedvelin ID sutununda iki eyni sey ola bilmez. primary oldugundan. umud edirem ki, cavab qane eder.