ISqlGenerator Where mit RelationalOperators_Between

Hilfsmittel zum Erstellen von SQL-Anweisungen

ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Sten Schmidt » So 18. Mär 2012, 00:19

Hallo Zusammen,

ich habe beim Testen ein Probem beim Where mit dem RelationalOperators_Between-Operator:

Code: Alles auswählen

SqlAnweisung = SqlTools.SqlGenerator(SqlTools.SqlConverters.DaoSqlConverter) _
                  .From("Tab1") _
                  .Where("F2", RelationalOperators_Between, 2) _
                  .Select("F1", "F2").SelectField("Count(*)", "", "Anzahl") _
                  .ToString()

=> Select F1, F2, Count(*) As Anzahl From Tab1 Where (F2  2)
 


Der Operator wird im ResultString nicht ausgegeben und es ist aktuell (SVN Rev. 115) wohl nicht möglich einen 2. Parameter anzugeben.

(Schreibe dies hier rein weil das Projekt im Mantis noch nicht eingerichtet ist)

Viele Grüße
Sten Schmidt
Entwickler
 
Beiträge: 138
Registriert: Do 18. Mär 2010, 22:24
Accessversion: 2007, 2010
Access-Erfahrung: Experte

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Josef Pötzl » So 18. Mär 2012, 10:46

Hallo Sten!

Dir ist aber schon bewusst, dass der SqlGenerator noch nicht fertig ist? :)
Between ist ganz einfach noch gar nicht eingebaut .. muss ja auch nicht nicht, da es keinen Test dafür gibt, der fehl schlägt. :D

mfg
Josef
Josef Pötzl
Moderator
 
Beiträge: 751
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Sten Schmidt » So 18. Mär 2012, 13:23

Hi Josef,

Josef Pötzl hat geschrieben:Dir ist aber schon bewusst, dass der SqlGenerator noch nicht fertig ist? :)
Between ist ganz einfach noch gar nicht eingebaut ..


war mir schon klar. :)

Ich wollte damit nur indirekt sagen, dass ich hier ein Strukturproblem sehe, wobei ich ehrlich gesagt auch nicht weiß wie man das am besten Lösen kann.

Also wenn ich folgendes Benutze:

Code: Alles auswählen

...
selectQuery.Where("F1", RelationalOperators.Between, 1, 2);
...
 


... und mal angenommen es gäbe schon eine entsprechende Überladug für den zweiten Parameter in:

Code: Alles auswählen

    public interface IFieldCondition : ICondition
    {
        IField Field { get; set; }
        RelationalOperators Operator { get; set; }
        object Value { get; set; }
    }
 


.. dann ist mir noch nicht klar wie man sicherstellen könnte dass der User beim Verwenden des Where-Ausdrucks genau dann wenn der Operator auf "Between" steht auch zum Verwenden der zweiten Überladung gezwungen werden könnte (z.B. durch Kompiler-Fehler).

Oder denke ich zu kompliziert??

Gruß Sten
Sten Schmidt
Entwickler
 
Beiträge: 138
Registriert: Do 18. Mär 2010, 22:24
Accessversion: 2007, 2010
Access-Erfahrung: Experte

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon FireWalkerHH » So 18. Mär 2012, 14:00

Mhh, also wenn schon zur Kompilierzeit ein Fehler auftreten soll, dann müsste man eine zusätzliche Where-Funktion einbauen.

Code: Alles auswählen
selectQuery.WhereBetween("F1", 1, 2);


Und dann könnte man den Operator 'Between' auch weglassen.


Oder es gibt eine Überladung vom 'Where' die als Parameter ein Field, und zwei Values erwartet.

Und das IN fehlt ja auch noch: Da stelle ich mir folgendes vor:
Eine 'Where'-Funktion die ein Field und eine ValueList bekommt und ein 'Where' das ein Field und ein SubSelect bekommt.

Gruß,
Thomas
Thomas Franzek

Diese Signatur wurde mit 100% chlorfrei gebleichten, glücklichen Elektronen erzeugt.
Diese entstammen keiner Lagerelektronenhaltung und werden nicht zu ihrer Arbeit gezwungen
FireWalkerHH
Entwickler
 
Beiträge: 57
Registriert: Mo 18. Okt 2010, 12:13

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Josef Pötzl » So 18. Mär 2012, 14:02

Hallo!

In Net brauchen wir keinen 2. Value-Parameter.

Code: Alles auswählen
selectQuery.Where(new Field("F1"), RelationalOperators.Between, New BetweenValue(1, 2));


Das hindert zwar den Nutzer der Lib nicht daran folgendes zu schreiben:
Code: Alles auswählen
selectQuery.Where(new Field("F1"), RelationalOperators.Between, 1);

... aber dann kann man ja eine Exception auslösen. Irgendwann wird er sich das schon merken, dass man für Between 2 Parameter übergeben muss.

Damit man es zum Compiler-Fehler kommt, müsste man eine extra Enum verwenden.
=>
Code: Alles auswählen
public ISqlGenerator Where(IField field, RelationalOperatorsMIt1Value relationalOperator, object value)

und
Code: Alles auswählen
public ISqlGenerator Where(IField field, RelationalOperatorsMit2Values relationalOperator, object value1, object value2)

bzw.
Code: Alles auswählen
public ISqlGenerator Where(IField field, RelationalOperatorsMit2Values relationalOperator, object[2] values)

bzw.
Code: Alles auswählen
public ISqlGenerator Where(IField field, RelationalOperatorsMit2Values relationalOperator, IExtraInterface values)


Ich würde mir das aber für den Anfang nicht antun und auf etwas Mitdenken des Programmiers hoffen. :)


Für VBA würde ich allerdings für die vereinfachte Eingabe eine WhereBetween-Prozedur in der COM-dll gestalten.

mfg
Josef
Josef Pötzl
Moderator
 
Beiträge: 751
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Sten Schmidt » So 18. Mär 2012, 20:26

Josef Pötzl hat geschrieben:Für VBA würde ich allerdings für die vereinfachte Eingabe eine WhereBetween-Prozedur in der COM-dll gestalten.


Ja, darauf wird es wohl hinauslaufen, wobei sich mir dann die Frage stellt ob man das nich gleich für jeden RelationalOperator macht, weil so ehwig viele Varianten werden dabei ja nicht auftreten.

Vielleicht nur als Idee (Pseudocode):

Code: Alles auswählen


foo.Where.IsNot("F1", 0)
foo.Where.IsEqual("F1", 0)
foo.Where.IsLessThan("F1", 0)
foo.Where.IsGreaterThan("F1", 0)
foo.Where.IsLike("F1", 0)
foo.Where.IsBetween("F1", 0, 9)
foo.Where.IsIn("F1", ???)

 
Sten Schmidt
Entwickler
 
Beiträge: 138
Registriert: Do 18. Mär 2010, 22:24
Accessversion: 2007, 2010
Access-Erfahrung: Experte

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Josef Pötzl » So 18. Mär 2012, 20:32

Hallo!

Es fehlt noch:
foo.Where.IsEqualOrGreaterThan(...)
foo.Where.IsEqualOrLessThan(...)

+ alle mit Not, wobei man hier eine "WhereNot"-Klasse nutzen könnte:
foo.Where.Not.IsEqual("F1", 0)
foo.Where.Not.IsLessThan("F1", 0)
foo.Where.Not.IsGreaterThan("F1", 0)
foo.Where.Not.IsLike("F1", 0)
foo.Where.Not.IsBetween("F1", 0, 9)
foo.Where.Not.IsIn("F1", ???)
foo.Where.Not.IsEqualOrGreaterThan(...)
foo.Where.Not.IsEqualOrLessThan(...)

Ich finde, dass dann der Code etwas lästiger zu bedienen wird, da man dann nicht mehr "... Where(...).Where(...).Having(..)" schreiben kann.
Andererseits wird er vielleicht sogar (je nach Geschmack) lesbarer.

Einen Nachteil hat so ein Konstrukt aber: sobald man eine Bedingungsart ergänzt, muss man das COM-Interface ändern.
Bei der Variante mit Where(Element, Vergleichsparameter, Vergleichselement) muss man nur den Code dahinter anpassen, kann aber die COM-Schnittstelle unverändert lassen.

In der "reinen" .net-Lib will ich so etwas aber nicht haben, da man dort mit Überladungen arbeiten kann.

Mir selbst gefällt es für VBA so besser:
Code: Alles auswählen
foo.Where(Feld, RelationalOperators_Like, "abc*")


Between könnte ich mir z. B. auch so vorstellen:
Code: Alles auswählen
SqlGenerator.Where(Feld, RelationalOperators_Between, Array(von, bis))

'oder
With SqlGenerator
   .Where(Feld, RelationalOperators_Between, .BetweenParam(von, bis))
end With

'oder
With SqlGenerator
   .Where(.BetweenCondition(Feld, von, bis))
end With


mfg
Josef
Josef Pötzl
Moderator
 
Beiträge: 751
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Sten Schmidt » So 18. Mär 2012, 22:48

Hoi Zusammen,

habe jetzt mal versucht

Code: Alles auswählen

.WhereBetween("F1", 1, 2)
 


einzubauen, aber ich komme nur bis:

Code: Alles auswählen

Select F1, F2, F3 From TabA Where (F1 Between AccessCodeLib.Data.SqlTools.Sql.BetweenValue) Group By F2 Order By F1
 


Also für die Struktur der Lib braucht man ja ne Landkarte. :)

(Ich hol mir jetzt ein Bier, Feierabend für heute... :D )
Sten Schmidt
Entwickler
 
Beiträge: 138
Registriert: Do 18. Mär 2010, 22:24
Accessversion: 2007, 2010
Access-Erfahrung: Experte

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Josef Pötzl » Mo 19. Mär 2012, 08:20

Die Landkarte ists verfügbar - du kannst ein Klassendiagramm vom Visual Studio erstellen lassen. :)

Wenn du es dir das Prinzip ansiehst, ist das aber gar nicht so komplex.
Der SqlGenerator ist zum Zusammensetzen der SQL-Elemente. Der Converter konvertiert diese Sammlung in den jeweiligen Dialekt. Da bei Where, Having on On (vom Join) die gleiche Aufgabe mehrmals benötigt wird, übernimmt das ein ConditionConverter, um keinen Code wiederholen zu müssen.

=> Also einen Test für den ConditionConverter schreiben und dann Between dort einbauen.
Ich würde die Libs gerne testgetrieben entwickeln, da wir durch Tests vorab schon zeigen, wie etwas verwendet wird. Außerdem kann es uns dann nicht passieren, dass ein anderer einen Code anpasst und dabei etwas anders (das er vielleicht gar nicht kannte) nicht mehr läuft.

mfg
Josef
Josef Pötzl
Moderator
 
Beiträge: 751
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: ISqlGenerator Where mit RelationalOperators_Between

Beitragvon Sten Schmidt » Mo 19. Mär 2012, 11:44

Moin,

Josef Pötzl hat geschrieben:=> Also einen Test für den ConditionConverter schreiben und dann Between dort einbauen.
Ich würde die Libs gerne testgetrieben entwickeln, da wir durch Tests vorab schon zeigen, wie etwas verwendet wird. Außerdem kann es uns dann nicht passieren, dass ein anderer einen Code anpasst und dabei etwas anders (das er vielleicht gar nicht kannte) nicht mehr läuft.


Kann man die Tests aus Visual Studio heraus starten? Dort gibt es ja das Menü "Test", aber das hat nix mit NUnit zu tun.
Bzw. wäre es das "korrekte" Vorgehnen wenn ich die foo.Test.dll per Drag&Drop in das NUnit-Tool ziehe oder geht das auch einfacherer?
Sten Schmidt
Entwickler
 
Beiträge: 138
Registriert: Do 18. Mär 2010, 22:24
Accessversion: 2007, 2010
Access-Erfahrung: Experte

Nächste

Zurück zu SqlTools

cron