Autor Zpráva
quatzael
Profil
Mám SQL dotaz, na to, abych ověřil existenci záznamu:

SELECT COUNT(*) AS calnum FROM table WHERE ...

No a za tím WHERE mám desítky podmínek oddělených AND. Dal jsem to do cyklu foreach, protože mám ty názvy sloupců a hodnoty v poli. Jenže ten syntax je takový, že když se jedná o řetězec, tak tam jsou uvozovky a když je to číslo, tak musí být bez uvozovek.

A mě by zajímalo, jak co nejefektivněji provádět ten dotaz. Protože bez toho cyklu foreach se mi to dělat moc nechce, a roztřiďovat to pole do dvou jiných podle datových typů je taky náročnější.

Dalo by se nějak otestovat každý sloupec na datový typ? Abych si mohl do druhého pole uložit datové typy pro každý sloupec a podle toho správně napsat ten sql dotaz..
Kajman
Profil
Obecně můžete z databáze zjistit datové typy sloupců tabulky. Záleží na zvolené databázi, postup se liší.

Bez for cyklu to asi také půjde. Z toho popisu není jasné, co děláte, ale buď použijete ve where spojení OR nebo vrátíte více řádků díky UNION ALL.
quatzael
Profil
Kajman:
Obecně můžete z databáze zjistit datové typy sloupců tabulky.
A jak teda? Používám SQL (MySQL), v PHP mysqli..

Z toho popisu není jasné, co děláte, ale buď použijete ve where spojení OR nebo vrátíte více řádků díky UNION ALL.
Moc nerozumím. Mám tam jen podmínky pro většinu slopců, tzn.:
WHERE column1 = 'value1' AND column2 = value2 AND ...
Všude je jen AND, žádný OR.

UNION ALL je přeci jen pro získání dat z více tabulek, ne? Já to mám jen v jedné.
Kajman
Profil
quatzael:
A jak teda?
http://dev.mysql.com/doc/refman/5.5/en/columns-table.html

Všude je jen AND, žádný OR.
Opakuji, že není jasné, proč používáte for cyklus. Pokud hledáte, zda je calnum alespoň pro jednu kombinaci různý od nuly, tak stačí
WHERE (column1 = 'value1' AND column2 = value2 AND ...) OR (column1 = 'value2' AND column2 = 42 AND ...) ... 

UNION ALL je přeci jen pro získání dat z více tabulek, ne?
Ne, klidně můtete používat jen jedinou tabulku nebo i žádnou.
Alphard
Profil
Já to chápu tak, že cílem je dynamicky vygenerovat jednoduchý SQL dotaz podle nějakého pole. Všechny podmínky mají být spojené AND, ale mají různé datové typy, toť vše.

když je to číslo, tak musí být bez uvozovek
Jaká databáze? Třeba MySQL si stringy přetypuje na čísla, sice to bude stát nějaký čas, ale jestli to zase ušetří něco v PHP...
Také se lze rozhodovat podle hodnot samotných, když hodnota projde is_numeric(), vložit jako číslo, když ne, escapovat jako řetězec.
quatzael
Profil
Kajman:
Opakuji, že není jasné, proč používáte for cyklus.
Protože těch sloupců tam mám opravdu hafo (cca 120) a všechno to vypisovat ručně je šílený. Takových tabulek mám několik. A jelikož už mám vytvořený asociativní pole (přímo s názvy sloupců v tabulce) s hodnotami, které chci ověřit, tak mi to příjde jako daleko rychlejší způsob.

Jenže je problém, že některé sloupce jsou číselnýho typu a u toho se nepíšou ty uvozovky, takže to musím v tom cyklu nějak zohlednit..
Kajman
Profil
Alphard:
vygenerovat jednoduchý SQL dotaz podle nějakého pole

Aha. Tak jestli to je takhle jednoduché, tak zmínky o OR a UNION se mohou ignorovat. Obával jsem se, že se dělá více dotazů ve foreach, ne jeden díky foreach.
quatzael
Profil
Alphard:
Já to chápu tak, že cílem je dynamicky vygenerovat jednoduchý SQL dotaz podle nějakého pole. Všechny podmínky mají být spojené AND, ale mají různé datové typy, toť vše.
Přesně tak!:o)

Jaká databáze? Třeba MySQL si stringy přetypuje na čísla, sice to bude stát nějaký čas, ale jestli to zase ušetří něco v PHP...
Určitě? Je to MySQL, jenže právě jsem to tam zadal všechno s těma uvozovkama a neprošlo to, tak jsem myslel, že je chyba v tomhle.. Možná tam mám ještě něco špatně.

když hodnota projde is_numeric(), vložit jako číslo, když ne, escapovat jako řetězec.
Nevadí to zase naopak obráceně? Tzn. vkládat číslo do varchar sloupce?
Escapoval jsem všechny hodnoty, včetně čísel pomocí mysqli_real_escape_string. To je taky špatně?


Kajman:
Aha. Tak jestli to je takhle jednoduché, tak zmínky o OR a UNION se mohou ignorovat.
Jednoduchý sice jo, ale s těmi různými datovými typy je to horší..
Alphard
Profil
quatzael [#8]:
Chybu bych hledal jinde. Alespoň ve výchozím nastavení to určitě jde.
quatzael
Profil
Alphard, Kajman:
Chybu bych hledal jinde. Alespoň ve výchozím nastavení to určitě jde.
tak jsem tam zkusil dát jen dvě podmínky a už to funguje (příkaz se vykoná)..
Jenže když tam hodím ty číselný hodnoty jako řetězce, tak to bere jako že podmínka splněná není. A hodí výsledek 0 jako počet řádků splňující danou podmínku..


Alphard, Kajman:
Tak jo, měl jsem tam trošku jinak pojmenovaný jeden sloupec, takže to nebralo.. Ale pořád to neumí brát string s číslem jako číslo..


A jak teda lze zjistit jaký datový typ sloupec používá? Je na to nějaký SQL příkaz/dotaz?
Kajman
Profil
quatzael:
A jak teda lze zjistit jaký datový typ sloupec používá? Je na to nějaký SQL příkaz/dotaz?

Viz odkaz v [#4]
quatzael
Profil
Kajman:
Jo, sorry já jsem to potom úplně přehlídl. A ten výsledek toho dotazu si taky můžu exportovat do asociativního pole?
A je to vůbec dobrej nápad to dělat v cyklu, který se opakuje 120krát?? Není to moc velká zátěž na databázi?
Kajman
Profil
quatzael:
A je to vůbec dobrej nápad to dělat v cyklu, který se opakuje 120krát?

Není. Udělejte to jednou ještě před cyklem.
quatzael
Profil
Kajman:
No ale já z toho "návodu" opravdu nevím jak sestavit ten dotaz.

Když tam zadám:
SELECT COLUMN_NAME, DATA_TYPE
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE table_name = 'nazev_tabulky'

tak mi vyjede jen info pro první sloupec (že id je [/pre]int[pre]). Ale já to potřebuju vědět pro všechny sloupce..

A potřeboval bych to dostat do asociativního pole, kde bych měl jako klíč název sloupce a jako hodnotu datový typ.
Alphard
Profil
Mně tedy dotaz
SELECT * FROM `COLUMNS` WHERE `TABLE_NAME` =  'actions'
vrací všechny sloupce, raději jsem to zkoušel na čtyřech různých serverech, i když myslím, že všude, kde funguje Adminer nebo PMA to musí fungovat.

Ale pořád to neumí brát string s číslem jako číslo.
Taktéž, dělá se to běžně, takto si zjednodušuje život třeba i zmíněný Adminer, standardně to funguje.

Myslím, že chybu děláte někde vy. Už i nápad dotazovat se na totéž 120x nasvědčuje, že by bylo vhodné u práce více přemýšlet :-) bohužel vaše příspěvky nejsou dostatečné k tomu, abychom mohli identifikovat chybu.
quatzael
Profil
Alphard:
Ale já se na to nechci dotazovat 120x. Já chci před tím cyklem foreach si jednorázově zjistit datový typy sloupců a získat asociativní pole, kde by se klíč rovnal názvu sloupce a hodnota byla ten datový typ. Ale nejde to. Ten dotaz:

SELECT COLUMN_NAME, DATA_TYPE
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE table_name = 'nazev_tabulky'

mi normálně funguje v phpMyAdmin. Ale když chci z toho dostat pole v tom PHPčku, tak mi to vrátí jenom první sloupec (id = int).

A já potřebuju všechny sloupce.


Alphard:
Prostě je tam jen tohle:

array(4) { [0]=> string(2) "id" ["COLUMN_NAME"]=> string(2) "id" [1]=> string(3) "int" ["DATA_TYPE"]=> string(3) "int" }


Prostě potřebuju, abych dostal pole, kde bych mohl získávat datový typ jednoduše podle klíče, tedy tímto způsobem:
echo $array['column1']; /// vypíše "int", pokud sloupec s názvem "column1" bude mít datový typ integer..

Nevím jak už to srozumitelněji popsat..
Alphard
Profil
Kde se ten výsledek bere? Ukažte PHP kód zpracování toho dotazu (relevantní část).
Ušetřil byste si hodně starostí, kdybyste používal třeba dibi, stačilo by napsat fetchPairs('column_name', 'data_type').
quatzael
Profil
Alphard:
Mám tam tohle:

$query = "SELECT COLUMN_NAME, DATA_TYPE
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE table_name = 'nazev_tabulky'";
$qresult = mysqli_query($db_connect, $query ); 
$row = mysqli_fetch_assoc($qresult); 



Alphard:
Ušetřil byste si hodně starostí, kdybyste používal třeba dibi,
Vůbec nevím co to je a jak to funguje..

stačilo by napsat fetchPairs('column_name', 'data_type').
Kam to mám ale napsat..
Alphard
Profil
Fajn, konečně se někam dostáváme, mysqli_fetch_assoc() zpracovává výsledek po jednotlivých záznamech, tudíž se musí volat v cyklu. To jste ještě nikdy nezpracovával víceřádkový výsledek z databáze?

var_dump(mysqli_fetch_assoc($qresult));
var_dump(mysqli_fetch_assoc($qresult));
var_dump(mysqli_fetch_assoc($qresult));
Vypíše první tři řádky.
quatzael
Profil
Alphard:
To jste ještě nikdy nezpracovával víceřádkový výsledek z databáze?
Ještě opravdu ne.

Jak to teda mám volat v cyklu? Jakou proměnnou mám dát do toho foreach, aby to proběhlo pro všechny sloupce?


Alphard:
Aha. Už jsem na to přišel. Má tam být cyklus while.. Ale jak jsem to mohl vědět?
Kajman
Profil
quatzael:
Ale jak jsem to mohl vědět?

Ještě jste nikdy nezpracovával select, který vrací více řádků?

A do podmínky where si přidejte
AND table_schema='nazev_databaze'
Pokud by byl stejný název tabulky ve více schématech, do kterých máte právo, a tabulky by nebyly stejné, mohlo by to bez toho omezení zlobit.
quatzael
Profil
Kajman:
Ještě jste nikdy nezpracovával select, který vrací více řádků?
Aha, jo. Úplně se mi ve dvě ráno vykouřilo z hlavy, že mám ten cyklus while u několika scriptů takhle použitej..

A do podmínky where si přidejte
AND table_schema='nazev_databaze'AND table_schema='nazev_databaze'Pokud by byl stejný název tabulky ve více schématech, do kterých máte právo, a tabulky by nebyly stejné, mohlo by to bez toho omezení zlobit.

Není to už náhodou očištěno, tím že v příkazu: $qresult = mysqli_query($db_connect, $sql_query); uvádím odkaz na konkrétní databázi?
Kajman
Profil
quatzael:
Není to už náhodou očištěno

Ne.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: