Autor Téma: Objekt parametr je nesprávně definován  (Přečteno 9524 krát)

Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
Objekt parametr je nesprávně definován
« kdy: 20-12-2012, 19:14:40 »
Dobrý den,
používám ADO+ delphi2007+MSSQL server.  Zapisuji do tabulky pomocí adoquery textové řetězce. Pokud jakýkoliv retezec kdekoliv obsahuje kombinaci znaků ": (slozene uvozovky a dvojtecka) sql prikaz vzdy skonci chybou "Objekt parametr je nesprávně definován. Byly poskytnuty nekonzistentní nebo neúplné informace" Pritom kdyz pouziju tyto znaky libovolne krat samostatne nebo treba i jen v opacne kombinaci t.j. :" chyba nenastane a hodnoty se do tabulky ulozi vcetne techto znaku. Asi je tento dotaz spatne zarazen v sekci MSSQL  protoze jsem dodatecne zjistil, ze se totez stane pokud vkladam data stejnym zpusobem pomoci adoquery ale do db Accesu. Jestlize uplne stejny sql dotaz obsahujici ": provedu nad danou databazi v SQL server management studiu tak se provede uspesne a hodnoty se ulozi.
dekuji za rady.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Objekt parametr je nesprávně definován
« Odpověď #1 kdy: 20-12-2012, 19:26:48 »
asi děláš něco blbě - :param nebo @param se používá pro identifikaci parametrů dotazu, to by ale nemělo mít vliv pokud je dvojtečka přímo ve stringu. Nicméně stejně je lepší data předávat přes parametry a neskládat SQL dotazy do stringu.

Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
Re:Objekt parametr je nesprávně definován
« Odpověď #2 kdy: 20-12-2012, 19:33:14 »
prikladam obrazek
- jakakoliv jina kombinace znaku " a : v retezci v dotazu se se provede a ulozi, jen kombinace ": skonci uvedenou chybou

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Objekt parametr je nesprávně definován
« Odpověď #3 kdy: 20-12-2012, 19:34:28 »
spíš ukaž ten zdroják

Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
Re:Objekt parametr je nesprávně definován
« Odpověď #4 kdy: 20-12-2012, 21:19:06 »
uplne nacisto abych se oprostil od mozneho balastu jsem splacal jednoduchy program, ktery zapisuje 1 retezec do 1 tabulky, dela to samozrejme taky, prilozim sem cely zdrojak v zipu. Samozrejme je to bez jakehokoliv osetreni jen nutny kod.
klicove je samozrejme
adoquery1.SQL.text:='insert into tabulka1 (nejakytext) values('''+LabeledEdit1.text+''')';
adoquery1.ExecSQL;

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Objekt parametr je nesprávně definován
« Odpověď #5 kdy: 20-12-2012, 21:35:13 »
Je možný, že se to prostě blbě parsuje. Moc bych to ale neřešil, prostě to předělej na dotazy s parametrama, ukázka je třeba tady - http://www.4itdevelopers.net/cteni__a_zapis_binarnich_dat_do_databaze_v_delphi.aspx. Pak tam můžeš zapisovat třeba i binární data, nemusíš řešit escapování znaků atd.

Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
Re:Objekt parametr je nesprávně definován
« Odpověď #6 kdy: 20-12-2012, 22:01:23 »
tak jsem to predelal pres paramatry a funguje To! To je senzace. Tim padem mi to vyresi to, ze mi uzivatele obcas zahlasi tuto chybu, ne casto ma to jen neco pres 100 uzivatelu a nekdo se ozve tak jednou za par mesicu - zrejme se trefi do nejake podobne kombinace znaku pri vkladani zakazek, takze toto reseni pokryje zrejme vsechny pripady coz je super. Stejne je to ale podivna anomalie, nikde jsem o tom nic nevygooglil ani zadna magie s escapovanim to nevyresila az toto. Opravdu MOC diky.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2580
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Objekt parametr je nesprávně definován
« Odpověď #7 kdy: 21-12-2012, 09:13:44 »
insert into tabulka1 (nejakytext) values('''+LabeledEdit1.text+''')
...
Stejne je to ale podivna anomalie,

To neni zadna anomalie, ale zakonitost: nech si vypsat ten tvuj rucne sestaveny prikaz po rozvinuti tj. po dosazeni tech tvych pochybnych hodnot a zvaz, jestli je to stale jeste korektni SQL prikaz. Neni. V cesku je rucni skladani SQL prikazu znacne rozsireny nesvar, mozna proto, ze se jmena jako O'Hara vyskytuji vzacne, jinak by DB propramatori zahy zjistili, ze tudy ceste nevede.

Zaver z toho je jediny: rucne se SQL prikazy neskladaji (da se to sice udelat spravne, ale kdo by se rucne matlal s SQL escapovanim, kdyz to za nej uz udelali na urovni konektivity k prislusne DB. A spravne s respektovanim specifik konkretniho RDBMS).

Ohledne googleni: zkus se podivat na hesla:
  • Parametrized SQL
  • SQL Escaping
  • SQL injection


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4342
  • Karma: 38
    • Verze Delphi: XE7 professional
Re:Objekt parametr je nesprávně definován
« Odpověď #8 kdy: 21-12-2012, 10:16:42 »
V access máš priamo napísané, že pri použití diakritiky či zvláštnych znakov to musíš dať do []. Snáď nekecám. Záleží aj aké ANSI používaš. Potom tam musíš dostať " ".
Samozrejme je to ešte závislé aj na tom v akom prostredí to robíš.
Jednoznačne všade a vždy používaj parametre. Je to aj ochrana pred SQL injection.
« Poslední změna: 21-12-2012, 11:09:47 od Stanislav Hruška »
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
Re:Objekt parametr je nesprávně definován
« Odpověď #9 kdy: 21-12-2012, 10:25:04 »
Díky za tipy, ono právěže jsem si nevšiml po dosazení proměnných, že by celý sql prikaz jako retezec byl nejak nekorektni. Je jasne, ze kdyby v retezci byly nejake ridici znaky jako procento nebo jednoduche uvozovky tak se musi escapovat ale tady nejsou proto i kdyz ten samy sql dotaz (doplneny o hodnoty) jako retezec zadam v management studiu tak projde. Pres adoquery neprojde, ale staci dotcene znaky prohodit a projde. Co je spatneho na dvojtecce a slozenych uvozovkach v textovém řetězci když samostatně v sql prikazu projdou ale když je dám vedle sebe tak neprojdou ale pouze v kombinaci ": v opacne :" projdou ale to plati jen pres ado, naprimo ve studiu projde vsechno. To jsem povazoval za anomalii, ale nechci se hadat, jsem moc rad, ze jsem se dozvedel o tech paramatrech a funguje to, diky vsem za tipy obzvlaste uzivateli MI.CHAL.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Objekt parametr je nesprávně definován
« Odpověď #10 kdy: 21-12-2012, 10:48:52 »
V Management studiu to projde nejspíš z toho důvodu, že se ta query zpracovává trochu jinak, tam ty parametry nemáš jak zadat, pokud nenapíšeš odpovídající dotaz (když se podíváš profilerem, co posílá TAdoQuery, tak je to něco jako sp_executesql 'sql', parametry). U TAdoQuery se dá taky nějak nastavit, aby to ten string neparsovalo a nepřidávalo parametry ručně, pak by to třeba fungovalo taky. Ale určitě je lepší použít parametrizované dotazy - kvůli sql injection, výkonu atd

Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
Re:Objekt parametr je nesprávně definován
« Odpověď #11 kdy: 21-12-2012, 12:27:41 »
fakt ze jo, Adoquery ma vlastnost Paramcheck v defaultu nastavenou na true, pokud to dam na false tak projde v dotazu jak ": tak i :" bezproblemu! To je parada, takze jako rychle reseni nez dotazy predelam na paramatry staci vypnout vlastnost Paramcheck. Diky, super.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2580
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Objekt parametr je nesprávně definován
« Odpověď #12 kdy: 21-12-2012, 12:34:36 »
Díky za tipy, ono právěže jsem si nevšiml po dosazení proměnných, že by celý sql prikaz jako retezec byl nejak nekorektni. Je jasne, ze kdyby v retezci byly nejake ridici znaky jako procento nebo jednoduche uvozovky tak se musi escapovat ale tady nejsou proto i kdyz ten samy sql dotaz (doplneny o hodnoty) jako retezec zadam v management studiu tak projde.
Je treba rozlisovat mezi mezi SQL prikazem, ktery primo vykonava RDBMS a prikazem, ktery nejprve predzvejka DB connectivita: ta zpravidla rozlisuje pozicni a pojmenovane parametry. Pojmenovany parametr byva nejake symbolicke jmeno s dvojteckou jako prefixem. A stejne je treba rozlisovat, kdo ten prikaz vykonava tj. uvedomit si, kdo se vsechno podili na jeho zpracovani.

Co je spatneho na dvojtecce a slozenych uvozovkach v textovém řetězci když samostatně v sql prikazu projdou ale když je dám vedle sebe tak neprojdou ale pouze v kombinaci ": v opacne :" projdou ale to plati jen pres ado
Posloupnost :'' nevyhodnoti jako pojmenovany parametr, zatimco '':<neco> bere jako neplatny pojmenovany parametr, cemuz ostatne napovida u chyba v %subj%

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4342
  • Karma: 38
    • Verze Delphi: XE7 professional
Re:Objekt parametr je nesprávně definován
« Odpověď #13 kdy: 21-12-2012, 13:00:37 »
// staci vypnout vlastnost Paramcheck
To by som nerobil. Ak Ti v budúcnosti niečo vybehne, tak nebudeš vedieť prísť na chybu!
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
problem s parametrizovanym query na sqlite
« Odpověď #14 kdy: 23-12-2012, 13:29:53 »
mam starsi verzi projektu, ktera neni v MSSQL ale SQLite, kdyz jsem prepsal sql prikaz pro ukladani zakazky na "parametrizovany", nastal trochu jiny problem s ukladanim textovych retezcu. A totiz pokud je retezec prazdny a pouziji parametrizovany update tak se tento prazdny retezec do databaze neulozi jako prazdny retezec '' ale jako hodnota NULL. Pokud pouziji stejny sql update prikaz neparametrizovane - jako text, ulozi se do databaze ne jako NULL ale jako prazdny retezec''
Problem potom nastane pri vyhledavani pomoci neparametrizovanych sql prikazu - ktere si uzivatel muze sam zadavat jako text. Uvedu zjednoduseny priklad:
kdyz poslu prikaz neparametrizovane:
update TABULKA1 set vysledek='' where cislozakazky=5300
potom v databazi v zakazce 5300 v poli vysledek bude opravdu prazdny retezec '' - retezec s nulovou delkou
ale jestlize ten prikaz poslu parametrizovane nebude tam '' ale NULL
Takze kdyz si potom uzivatel zada neco jako select * from tabulka1 where vysledek='' potom se mu tato zakazka nevyfiltruje !!!
To ze jsou v databazi u zaznamu misto prazdnych retezcu hodnoty NULL (jen u zaznamu ulozenych parametrizovane) jsem zjistil az kdyz jsem to dumpnul pomoci sqlite3.exe
Jak by slo tento problem vyresit ? potreboval abych se parametrizovane ukladaly prazdne retezce a ne hodnoty NULL. Asi to souvisi uz s deklaraci databaze, kdybych tam specifikoval ze hodnota nemuze byt nulll.  ale rekneme, ze to nemuzu zmenit u existujicich databazi plnych dat.
dekuji vsem za rady a omlouvam se, ze toto uz nesouvisi s MSSQL ale navazuje to na prvotni dotaz jehoz resenim byly parametrizovane dotazy - ted bych je nemel pouzit kvuli novemu problemu a jsem tam kde jsem byl.

Offline mjseven

  • Mladík
  • **
  • Příspěvků: 68
  • Karma: 6
    • Verze Delphi: D7, D2006, XE2, Lazarus
Re:Objekt parametr je nesprávně definován
« Odpověď #15 kdy: 23-12-2012, 13:50:11 »
V MSSQL existuje příkaz ISNULL().
Dotaz pro vyhledávání select * from tabulka1 where vysledek='' by pak vypadal takhle:


select * from tabulka1 where ISNULL(vysledek, '') = ''

Což znamená, že v případě kdy pole je NULL tak má místo NULL použít hodnotu ''. Pak ti ten dotaz vrátí vše co má v poli výsledek NULL nebo ''
 


Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2580
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:problem s parametrizovanym query na sqlite
« Odpověď #16 kdy: 23-12-2012, 14:59:27 »
Jak by slo tento problem vyresit ? potreboval abych se parametrizovane ukladaly prazdne retezce a ne hodnoty NULL. Asi to souvisi uz s deklaraci databaze, kdybych tam specifikoval ze hodnota nemuze byt nulll.  ale rekneme, ze to nemuzu zmenit u existujicich databazi plnych dat
Uz jsem s SQLite dlouho nic nedelal a kdyz, tak pres vlastni komponenty.

Ale Sqlite3 tu mam ve verzi 3.5.6 a pomoci nej ulozim prazdny string do DB jako prazdny string i do pole deklarovaneho jako NULL, takze to budou mit na svedomi nejspis komponenty, ktere s SQLite pouzivas - asi nejjednoduzsi bude protrasovat, co ty komponenty s hodnotu parametru delaji a zjistit, jake jsou moznosti (jine komponenty, opravit stavajici, volat primo Sqlite3 API resp. napsat si vlastni)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2580
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Objekt parametr je nesprávně definován
« Odpověď #17 kdy: 23-12-2012, 15:06:50 »
V MSSQL existuje příkaz ISNULL().
Tak ona je to funkce a ne prikaz  ;) a Sqlite ji umi taky http://www.sqlite.org/lang_corefunc.html#ifnull. Ale funguje i obycejna koalice
Kód: SQL [Vybrat]
  1. SELECT * FROM tabulka1 WHERE COALESCE(vysledek, '') = ''


Offline rob.

  • Nováček
  • *
  • Příspěvků: 38
  • Karma: 0
Re:Objekt parametr je nesprávně definován
« Odpověď #18 kdy: 23-12-2012, 15:29:15 »
diky za tipy, ifnull by to mohlo resit akoratze uzivatele maji ulozeny svoje prednastavene filtry a ty by se musely vsechny upravit protoze jinak by jim polovina filtru (ktere maji ulozeny uz treba rok) najednou s aktualizovanou verzi programu prestala fungovat. Proto budu primarne zkouset to jak ukladat prazdne retezce jako retezce a ne NULL, rozpitvat komponenty (pouzivam Aducom) je mozna cesta ale na to jsem dost amater. Neslo by to pres nejaky trigger ? Nebo je to moc "prasecina"? Jakoze by ten trigger automaticky pri update zaznamu zmenil null na ''.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2580
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Objekt parametr je nesprávně definován
« Odpověď #19 kdy: 23-12-2012, 16:48:40 »
Neslo by to pres nejaky trigger ? Nebo je to moc "prasecina"? Jakoze by ten trigger automaticky pri update zaznamu zmenil null na ''.
Klidne bych to before triggerem udelal - akorat asi budou muset (uz si to nepamatuju) byt dva: jeden pro insert, druhy pro update.