HDSoftware Skrevet 3. januar 2018 Del Skrevet 3. januar 2018 Folkens. Har følgende behov:I våre programmer brukes SQL statements både fra EntityFramework og fra andre drivere som sender SQL statements rett til SQL serveren. Jeg har behov for å lure inn et WHERE i samtlige statements som sendes uavhengig hvor de kommer ifra. Tenkte først å bruke en TRIGGER på SQL servere, men det finnes ikke for SELECT. I .NET verden hara jeg ikke noe problem med å lure dette inn fordi det er jeg som koder POCO klassene. Men i vårt andre verktøy (Clarion) så er det ikke slik. Der lages SQL uttrykket av et RTL. Det fine er at jeg har en callback i dette RTL'et som gir meg SQL uttrykket som blir sendt til SQL serveren før det sendes. Jeg har der muligheten til å modde uttrykket og dermed lure inn et WHERE uttrykk. Så kom neste problemstilling. Det å parse et generellt SQL uttrykk er ikek veldig enkelt fordi man i utgangspunktet ikke aner noe om uttrykket i det hele tatt og parse rutinene vil i så måte bli veldig kompliserte, og ikek minst, muligheten for feil er overhengende stor. Så tenkte jeg, kanskje EntityFramework har noe på lur her.Gitt følgende pseudokode: Public static string AddWhere(string Expression) { var SQLObjekt = ettellerannet.Parse(uttrykk); SQLObject.AddWhere("EnStoredProcedure()"); Return SQLObject.ToString(); } Er dette mulig i det hele tatt ? Lenke til kommentar
HDSoftware Skrevet 3. januar 2018 Forfatter Del Skrevet 3. januar 2018 Tror jeg fant noe her:https://www.codeproject.com/Articles/32524/SQL-Parser Lenke til kommentar
MailMan13 Skrevet 8. januar 2018 Del Skrevet 8. januar 2018 Du kan jo dekorere dem med noe sånt: with originalQuery as ( --orginal spørring ) select * from originalQuery where --nytt predikat Lenke til kommentar
HDSoftware Skrevet 8. januar 2018 Forfatter Del Skrevet 8. januar 2018 Du kan jo dekorere dem med noe sånt: with originalQuery as ( --orginal spørring ) select * from originalQuery where --nytt predikat Kjempebra ide. Det vil funke for meg.... Lenke til kommentar
HDSoftware Skrevet 12. januar 2018 Forfatter Del Skrevet 12. januar 2018 Du kan jo dekorere dem med noe sånt: with originalQuery as ( --orginal spørring ) select * from originalQuery where --nytt predikat Åhhh, nesten i mål :-) Ideen er kjempe god og virker nesten. Kanskje har du noe flere tips. Fordi her er følgende problem: Sett at uttrykket inneholder en join, og at begge tabellene som joines har kolonner med samme navn, da får jeg SQL error som sier at sub Query feiler med duplikat navn. Altså: SELECT a.Id, a.Navn, a.Nummer, b.Id, b.Beskrivelse from Personer a JOIN Telefoner b on a.Id = b.Id Dette gir forventet resultat, men WITH res as ( SELECT a.Id, a.Navn, a.Nummer, b.Id, b.Beskrivelse from Personer a JOIN Telefoner b on a.Id = b.Id ) SELECT * from res Dette derimot resulterer i en feil fordi kolonnen Id dukker opp TO ganger i RES. Vet det er enkelt å bare aliasifisere kolonnen, men dessverre er dette genererte uttrykk som ikke er så lett å modifisere. Finnes det en vei rundt dette tro? Lenke til kommentar
NoPain74 Skrevet 12. januar 2018 Del Skrevet 12. januar 2018 Du mener at with res (id1, navn,nummer, id2, beskrivelse) as ( select... Ikke virker? Lenke til kommentar
HDSoftware Skrevet 12. januar 2018 Forfatter Del Skrevet 12. januar 2018 Du mener at with res (id1, navn,nummer, id2, beskrivelse) as ( select... Ikke virker? Jeg kan være helt konkret: with res as ( SELECT TOP 2147483647 A.RECORDFILTER, A.NUMMER, A.NAVN, B.NUMMER, B.PERSONID, B.BESKRIVELSE, B.TELEFON FROM {oj PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID } WHERE ( A.NAVN = 'Ole' ) ORDER BY B.PERSONID ASC, B.BESKRIVELSE ASC ) select * from res Dette gir følgende feilmelding: Msg 8156, Level 16, State 1, Line 1 The column 'NUMMER' was specified multiple times for 'res'. Lenke til kommentar
NoPain74 Skrevet 12. januar 2018 Del Skrevet 12. januar 2018 Du mener at with res (id1, navn,nummer, id2, beskrivelse) as ( select... Ikke virker? Jeg kan være helt konkret: with res as ( SELECT TOP 2147483647 A.RECORDFILTER, A.NUMMER, A.NAVN, B.NUMMER, B.PERSONID, B.BESKRIVELSE, B.TELEFON FROM {oj PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID } WHERE ( A.NAVN = 'Ole' ) ORDER BY B.PERSONID ASC, B.BESKRIVELSE ASC ) select * from res Dette gir følgende feilmelding: Msg 8156, Level 16, State 1, Line 1 The column 'NUMMER' was specified multiple times for 'res'. Du henter ut feltet nummer fra både tabell a og tabell b. Jeg synes at det er rart at det ikke skulle virke hvis du gir de et alias. Kan du ikke prøve med denne? with (RecFilter, Nummer, Navn, Num, PersId, Beskrivelse, telefon) res as ( SELECT A.RECORDFILTER , A.NUMMER , A.NAVN , B.NUMMER , B.PERSONID , B.BESKRIVELSE , B.TELEFON FROM PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID WHERE A.NAVN = 'Ole' ORDER BY B.PERSONID ASC , B.BESKRIVELSE ASC ) select * from res Lenke til kommentar
HDSoftware Skrevet 14. januar 2018 Forfatter Del Skrevet 14. januar 2018 Du mener at with res (id1, navn,nummer, id2, beskrivelse) as ( select... Ikke virker? Jeg kan være helt konkret: with res as ( SELECT TOP 2147483647 A.RECORDFILTER, A.NUMMER, A.NAVN, B.NUMMER, B.PERSONID, B.BESKRIVELSE, B.TELEFON FROM {oj PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID } WHERE ( A.NAVN = 'Ole' ) ORDER BY B.PERSONID ASC, B.BESKRIVELSE ASC ) select * from res Dette gir følgende feilmelding: Msg 8156, Level 16, State 1, Line 1 The column 'NUMMER' was specified multiple times for 'res'. Du henter ut feltet nummer fra både tabell a og tabell b. Jeg synes at det er rart at det ikke skulle virke hvis du gir de et alias. Kan du ikke prøve med denne? with (RecFilter, Nummer, Navn, Num, PersId, Beskrivelse, telefon) res as ( SELECT A.RECORDFILTER , A.NUMMER , A.NAVN , B.NUMMER , B.PERSONID , B.BESKRIVELSE , B.TELEFON FROM PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID WHERE A.NAVN = 'Ole' ORDER BY B.PERSONID ASC , B.BESKRIVELSE ASC ) select * from res Jeg tenker at det blir feil fordi det nettopp IKKE er alias på feltene, men bare tabellene: SELECT a.Felt, b.Felt from tabell1 a join tabell2 b..... Man kunne aliasifisert dette slik: SELECT a.Felt as A_Felt, b.Felt as B_Felt.... Men dessverre har jeg ingen påvirkning på dette uttrykket så hvis jeg skal få gjort dette så må jeg lage en relativt komplisert parser. Håpet kansje det var en eller annen SQL automatikk på dette. subqueries har jo eksistert en stund Lenke til kommentar
HDSoftware Skrevet 14. januar 2018 Forfatter Del Skrevet 14. januar 2018 Du mener at with res (id1, navn,nummer, id2, beskrivelse) as ( select... Ikke virker? Jeg kan være helt konkret: with res as ( SELECT TOP 2147483647 A.RECORDFILTER, A.NUMMER, A.NAVN, B.NUMMER, B.PERSONID, B.BESKRIVELSE, B.TELEFON FROM {oj PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID } WHERE ( A.NAVN = 'Ole' ) ORDER BY B.PERSONID ASC, B.BESKRIVELSE ASC ) select * from res Dette gir følgende feilmelding: Msg 8156, Level 16, State 1, Line 1 The column 'NUMMER' was specified multiple times for 'res'. Du henter ut feltet nummer fra både tabell a og tabell b. Jeg synes at det er rart at det ikke skulle virke hvis du gir de et alias. Kan du ikke prøve med denne? with (RecFilter, Nummer, Navn, Num, PersId, Beskrivelse, telefon) res as ( SELECT A.RECORDFILTER , A.NUMMER , A.NAVN , B.NUMMER , B.PERSONID , B.BESKRIVELSE , B.TELEFON FROM PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID WHERE A.NAVN = 'Ole' ORDER BY B.PERSONID ASC , B.BESKRIVELSE ASC ) select * from res Heisan! Leste ikke hele meldingen din!!! Jeg skal jaggu prøve ut den varianten. Litt komplisert blir det fordi jeg alikevel må lage en slags parser som finner verdiene i SELECT delen. Det er i hvertfall en start... Lenke til kommentar
HDSoftware Skrevet 14. januar 2018 Forfatter Del Skrevet 14. januar 2018 Du mener at with res (id1, navn,nummer, id2, beskrivelse) as ( select... Ikke virker? Jeg kan være helt konkret: with res as ( SELECT TOP 2147483647 A.RECORDFILTER, A.NUMMER, A.NAVN, B.NUMMER, B.PERSONID, B.BESKRIVELSE, B.TELEFON FROM {oj PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID } WHERE ( A.NAVN = 'Ole' ) ORDER BY B.PERSONID ASC, B.BESKRIVELSE ASC ) select * from res Dette gir følgende feilmelding: Msg 8156, Level 16, State 1, Line 1 The column 'NUMMER' was specified multiple times for 'res'. Du henter ut feltet nummer fra både tabell a og tabell b. Jeg synes at det er rart at det ikke skulle virke hvis du gir de et alias. Kan du ikke prøve med denne? with (RecFilter, Nummer, Navn, Num, PersId, Beskrivelse, telefon) res as ( SELECT A.RECORDFILTER , A.NUMMER , A.NAVN , B.NUMMER , B.PERSONID , B.BESKRIVELSE , B.TELEFON FROM PERSONER A LEFT OUTER JOIN PHONES B ON A.NUMMER= B.PERSONID WHERE A.NAVN = 'Ole' ORDER BY B.PERSONID ASC , B.BESKRIVELSE ASC ) select * from res Heisan! Leste ikke hele meldingen din!!! Jeg skal jaggu prøve ut den varianten. Litt komplisert blir det fordi jeg alikevel må lage en slags parser som finner verdiene i SELECT delen. Det er i hvertfall en start... Ser ut som dette er veien å gå. En liten rettelse på syntaxen din though: SELECT (a, b, c) res as (..... <- Feilet SELECT res (a, b, c) as (..... <- Funker Takker for glimrende tips Lenke til kommentar
NoPain74 Skrevet 14. januar 2018 Del Skrevet 14. januar 2018 Så bra at det løste seg :-) Lenke til kommentar
oskaremil Skrevet 21. januar 2018 Del Skrevet 21. januar 2018 Du bruker .net ? Då lager du ikke en egen parser. Bruk Entity Framework eller Dapper (bare to av mange eksempler) for å mappe et SQL resultatsett til .net objekt. Lenke til kommentar
HDSoftware Skrevet 21. januar 2018 Forfatter Del Skrevet 21. januar 2018 Du bruker .net ? Då lager du ikke en egen parser. Bruk Entity Framework eller Dapper (bare to av mange eksempler) for å mappe et SQL resultatsett til .net objekt. Takker for tipset, men hvis du leser mitt innledende spørsmål så har ikke dette noe med .NET å gjøre Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå