Se kuka luulee tajuavansa, niin nyt on mahdollisuus yrittää eli ongelma on seuraava:
Käytän PHP:ta, Wintoosan IIS 5.0 web-palvelinta sekä MS SQL Server 7.0:aa kun teen kotisivuja. Koodi on seuraavanlainen:
$result = mssql_query( "if exists (select kuvaurl from kuvagalleria where koiraid = $koiraID and oletus = '1') begin select kuvaurl from kuvagalleria where koiraid = $koiraID and oletus = '1' end else select '00091' as kuvaurl" ); while ($a_row = mssql_fetch_array( $result ) ) { $kuvaurl = "$a_row[kuvaurl]"; }
Kaikki menee tuossa kyselyssä hyvin ja se toimiikin. Mutta sitten tuleekin se varsinainen ongelma eli jostain syystä tietokantayhteys sulkeutuu tuossa kohtaa eikä sitä pysty enää avaamaan millään keinolla??? Kysymys kuuluukin, että minkä takia?
Olen itse kohtuullisen aloittelija mutta nopeasti katsottuna onko tarkoituksellisesti "$result = mssql_query" eikös pitäisi olla mysql_query?
Siis tarkoititko, että se sulkeutuu kun sivu on tulostettu?
Suora tietokanta yhteys web-sivulta ei pysy auki koskaan sen jälkeen kun web sivu on lähetetty selaimelle, ellet käytä erillista data-komponenttia (wrapperi luokkakirjasto), jonka poolaat MTS:llä (Component Services). Tällöin voit käyttää samaa yhteyttä uudelleen.
Etkö saa yhteyttä auki seuraavalla sivun latauksella?
Jos teet homman oikein, tapat yhteyden sen jälkeen kun tietokanta suoritus päättyy. Muistathan, että MS SQL Serverissä on myös se politiikka, joka sallii vain tietyn määrän yhteyksiä palvelimelle... Jos jätät yhteyden roikkumaan ilman, että olet määritellyt riittävän määrän yhteyksiä se hylkää yhteyspyynnön.
lainaus:
Olen itse kohtuullisen aloittelija mutta nopeasti katsottuna onko tarkoituksellisesti "$result = mssql_query" eikös pitäisi olla mysql_query?
Abina. MS SQL Server != MySQL
Ja siis niin kuten antti tuossa sanoikin, yhteys tietokantaan loppuu aina kun skriptin suoritus loppuu.
lainaus:
Siis tarkoititko, että se sulkeutuu kun sivu on tulostettu?
Yhteys sulkeutuu ihan normaalisti kun sen koodissa käsken, mutta tuo kyseinen kysely aiheuttaa jotain outoa eli se ei anna tehdä kyselyitä eikä anna edes avata yhteyttä uudelleen mihinkään tietokantaan. Kun sama sivu avaa yhteyden 8:aan eri tietokantaan, mutta kun tekee tuon kyselyn, niin näkemiin kaikille yhteyksille: uusille ja vanhoille.
lainaus:
Suora tietokanta yhteys web-sivulta ei pysy auki koskaan sen jälkeen kun web sivu on lähetetty selaimelle, ellet käytä erillista data-komponenttia (wrapperi luokkakirjasto), jonka poolaat MTS:llä (Component Services). Tällöin voit käyttää samaa yhteyttä uudelleen.
Web sivun lähettämisen jälkeen ei ole tarvetta tietokantayhteydelle. Mutta kun tuo pirulainen ei anna edes avata uutta tietokantayhteyttä sen jälkeen kun suoritan tuon kyselyn.
lainaus:
Etkö saa yhteyttä auki seuraavalla sivun latauksella?
Tuon kyselyn jälkeen: en.
lainaus:
Jos teet homman oikein, tapat yhteyden sen jälkeen kun tietokanta suoritus päättyy.
Näin teen.
lainaus:
Muistathan, että MS SQL Serverissä on myös se politiikka, joka sallii vain tietyn määrän yhteyksiä palvelimelle... Jos jätät yhteyden roikkumaan ilman, että olet määritellyt riittävän määrän yhteyksiä se hylkää yhteyspyynnön.
Ongelma koskee vain ja ainoastaan tuota kyselyä PHP koodilla rakennettuna. Jos laitan esim. tuon kyselyn ennen muita kyselyitä jotka ovat samalla sivulla, niin yhteydet katkeaa eikä tuon kyselyn jälkeisiä kyselyitä voi enää suorittaa, koska tietokanta yhteyttä ei voi enää valita eikä avata. Tuo kysely aiheuttaa jonkinlaisen bugin jossakin, mutta missä?
lainaus:
Olen itse kohtuullisen aloittelija mutta nopeasti katsottuna onko tarkoituksellisesti "$result = mssql_query" eikös pitäisi olla mysql_query?
En käytä MySQL palvelinta vaan MS SQL Serveriä (7.0 sekä 2000).
Mitä connection-stringiä käytät? Laittaisitko sen tänne. Ongelma voi olla käyttämässäsi ODBC-ajurissa.
$db = "tietokannan_nimi";
$link = mssql_connect( "palvelimen_nimi");
if ( ! $link )
die( "Ei voida yhdistää tietokantaan" );
mssql_select_db( $db )
or die ( "Ei voi valita tietokantaa" );
Ongelma on todella outo, koska samalla sivulla on siis useita eri kyselysarjoja useisiin eri tietokantoihin samalla tietokantapalvelimella ja kun tuo mainitsemani kysely suoritetaan, niin yhteydet katkaistaan eikä yhteyttä voi enää avata kyselyille jotka ovat kyseisen kyselyn jälkeen.
Vaihtamalla tämän mainitsemani kyselyn sijaintia esim. ensimmäiseksi, niin tämä kyseinen kysely suoritetaan ja sen jälkeisiä kyselyitä ei. Jos laitat tämän kyseisen kyselyn viimeiseksi, niin kaikki kyselyt kyllä suoritetaan, mutta kun minun pitäisi saada SAMANTYYLINEN kysely suoritettua, mutta mitenkäs teet kun tietokantayhteys on poikki ja pysyy eikä sitä suostuta avaamaan enää.
Todennäköisesti ongelma liittynee tuohon IF EXISTS kohtaan SQL kyselyssä(?).
Kokeile kirjoittaa sama stored procedureen... itse en yleensä kirjoita mitään suorittavaa SQL:ää Koodiin vaan kutsun ne sprocin kautta...
Mielestäni et myöskään voi parsia tuota kyselyä noin... vaan:
"if exists (select kuvaurl from kuvagalleria where koiraid = " + $koiraID + " and oletus = '1') begin select kuvaurl from kuvagalleria where koiraid = " + $koiraID + " and oletus = '1' end else select '00091' as kuvaurl"
Muista, että kyseessä on tekstijono joka lähetetään SQL-palvelimelle. Näin ollen muuttujat ei siirry mukana...
lainaus:
Kokeile kirjoittaa sama stored procedureen... itse en yleensä kirjoita mitään suorittavaa SQL:ää Koodiin vaan kutsun ne sprocin kautta...
Miksi?
lainaus:
Mielestäni et myöskään voi parsia tuota kyselyä noin... vaan:
"if exists (select kuvaurl from kuvagalleria where koiraid = " + $koiraID + " and oletus = '1') begin select kuvaurl from kuvagalleria where koiraid = " + $koiraID + " and oletus = '1' end else select '00091' as kuvaurl"
Ei kyselyssä ole mitään vikaa sellaisenaan, se toimii aivan täydellisesti. Jos lisää tuohon kyselyyn lainausmerkit kuten esitit, niin tuloksena on virhe.
lainaus:
Muista, että kyseessä on tekstijono joka lähetetään SQL-palvelimelle. Näin ollen muuttujat ei siirry mukana...
Muuttuja täydennetään koodin lennossa ja ainakin minulla toimii todella hyvin.
Miksikö Stored Procedure?
Stored Proceduren avulla voit suorittaa paljon pidempiä komentosarjoja ja niiden suoritusnopeus on jopa 50 kertainen. Se vähentää myös transaktioita ohjelman ja tietokantapalvelimen välillä.
Yksi juttu mikä tuli mieleen voisit koittaa laittaa sen tietokantalinkin tuohon kyselyyn: $result = mssql_query("....",$link)
Ongelma saattaisi olla myös tuon $resultin kanssa, jos kysely palauttaa tyhjän arvon...
Onko mahdollista, että jäät ikuiseen looppiin tuon "while ($a_row = mssql_fetch_array( $result ) )"- lauseen kanssa. Minulla ainakin ikuinen looppi aiheuttaa tietokannan hyytymisen ja se ei enää suostu luomaan yhteyttä...
Lopuksi: Kirjoittamalla googleen "mssql_query problem" hakusanoiksi, löysin kattavan määrän virheraportteja ja käyttäjien kyselyitä aiheesta. Yksi yleinen ongelma oli palautetut tietotyypit.
lainaus:
Miksikö Stored Procedure?
Stored Proceduren avulla voit suorittaa paljon pidempiä komentosarjoja ja niiden suoritusnopeus on jopa 50 kertainen. Se vähentää myös transaktioita ohjelman ja tietokantapalvelimen välillä.
Tietokanta on pieni, vain reilut 100.000 riviä ja alle 50mb. Vaativatkin kyselyt antavat vastauksen alle sekunnissa vaikka samanaikaisesti kuormitus olisi yli 15 käyttäjää. Microsoftin kouluttajat eivät ainakaan yhdessä vaiheessa suositelleet proseduurien käyttöä kuin tiettyjen ehtojen täyttyessä joita en nyt tässä ala luettelemaan.
lainaus:
Yksi juttu mikä tuli mieleen voisit koittaa laittaa sen tietokantalinkin tuohon kyselyyn: $result = mssql_query("....",$link)
Kertoisitko idean tuossa?
lainaus:
Ongelma saattaisi olla myös tuon $resultin kanssa, jos kysely palauttaa tyhjän arvon...
Ei palauta. Kysely palauttaa vähintään arvon 00091 kuten kyselystä voit lukea.
lainaus:
Onko mahdollista, että jäät ikuiseen looppiin tuon "while ($a_row = mssql_fetch_array( $result ) )"- lauseen kanssa. Minulla ainakin ikuinen looppi aiheuttaa tietokannan hyytymisen ja se ei enää suostu luomaan yhteyttä...
Ei ole. Olen nyt kokeillut lähes kaikkia mahdollisia kyselytapoja ja nimenomaan IF sekä EXISTS sanojen käyttö kyselyssä aiheuttaa sen, että PHP katkaisee yhteyden kantaan eikä suostu sitä enää saman sivun muodostamisessa avaamaan uudelleen. Toki yhteys avautuu uudelleen kun muodostat sivun uudelleen tai kutsut toista sivua, mutta jos yrität suorittaa kyselyitä kyseisen kyselyn jälkeen, niin ei onnistu.
Tuntuu jonkinlaiselta bugilta. Microsoftin Knowledge ei tuonut valaistusta asiaan... :(
lainaus:
Lopuksi: Kirjoittamalla googleen "mssql_query problem" hakusanoiksi, löysin kattavan määrän virheraportteja ja käyttäjien kyselyitä aiheesta. Yksi yleinen ongelma oli palautetut tietotyypit.
Tutkin asiaa. Kiitos vinkistä.
lainaus:
Tietokanta on pieni, vain reilut 100.000 riviä ja alle 50mb. Vaativatkin kyselyt antavat vastauksen alle sekunnissa vaikka samanaikaisesti kuormitus olisi yli 15 käyttäjää. Microsoftin kouluttajat eivät ainakaan yhdessä vaiheessa suositelleet proseduurien käyttöä kuin tiettyjen ehtojen täyttyessä joita en nyt tässä ala luettelemaan.
MSCE-koulutuksessa suositeltiin nimenomaan kyseista ohjelmointitapaa jo pelkästään toteutettavien projektien tietokantatoiminnallisuuden hallinnoinnin keskittämisen kannalta. Kuka ja millä kurssilla MS-kouluttaja on sanonut ettei näin kannattaisi tehdä?
lainaus:
$result = mssql_query("....",$link)
Kertoisitko idean tuossa?
...,$link) asettaa käytettävän tietokanta connection-objektin mssql_query-kyselylle. Löytyy PHP:n dokumentaatiosta.
Query on muutoin oikein muotoiltu - siinä If Exists-lausekkeessa ei ole mitään vikaa ainakaan SQL Query Analyzerin mukaan...
Kyseessä oli PHP bugi. Ongelma ratkesi kun asensin uudemman version PHP:sta palvelimelle.
Ja MS kouluttajista kun puhutaan, niin kyseessä oli jokin paikallinen (eli kävin kurssia USA:ssa josta oli lähinnä puhe).
Ja SQL kyselyhän toimi täydellisesti, PHP vain jostain syystä bugasi.
Aihe on jo aika vanha, joten et voi enää vastata siihen.