рдбреЗрд▓реНрдлреА рдореЗрдВ SQL рдПрдореБрд▓реЗрд╢рди рдХреЗ рд▓рд┐рдП LINQ

рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рдиред
рдПрдХ рдмрдбрд╝рд╛ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд░реНрд╡рд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╣реИред рдХреНрд▓рд╛рдЗрдВрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдо SQL рд╕рд░реНрд╡рд░ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╢реАрд▓ SQL рдХреНрд╡реЗрд░реА рдмрдирд╛рддрд╛ рд╣реИред рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрдиреБрд░реЛрдз рд╣реИрдВ, рдирд┐рд░реНрдорд╛рдг рдХрд╛ рддрд░реНрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЛрдб рдореЗрдВ рдлреИрд▓рд╛ рд╣реБрдЖ рд╣реИред рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕рдордп рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд╕рд┐рдд рд╣реЛ рд░рд╣реА рд╣реИ, рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╕рдВрдХрд▓рдХ рдХреЛ рдЙрди рд╕рднреА рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдП рдЬрд╣рд╛рдВ рдЧреИрд░-рдореМрдЬреВрджрд╛ рдлрд╝реАрд▓реНрдб рдХреЛрдб рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ? рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХреИрд╕реЗ рдХрд░реЗрдВ рдХрд┐ рдПрдХ рдкреВрд░реНрдгрд╛рдВрдХ рдлрд╝реАрд▓реНрдб рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╕реМрдВрдкрд╛ рдЧрдпрд╛ рд╣реИ? рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдкрд╛рд╕реНрдХрд▓ рдХреЛрдб SQL рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рдХрд░реАрдм рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред
рдорд╛рди рд▓реАрдЬрд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рджреЛ рдЯреЗрдмрд▓ рд╣реИрдВ:
CREATE TABLE PERSON ( ID INTEGER NOT NULL, SURNAME VARCHAR(100) NOT NULL, EMPLOYMENT INTEGER, MOTHER INTEGER, FATHER INTEGER ); CREATE TABLE EMPLOYMENT ( ID INTEGER NOT NULL, DESCRIPTION VARCHAR(100) NOT NULL ); 

рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд╛рд╕реНрдХрд▓ рдореЗрдВ рдПрдХ SQL рдХреНрд╡реЗрд░реА рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рдЗрд╕рдореЗрдВ рддрд░реНрдХ рдХреА рддрд▓рд╛рд╢ рди рдХрд░реЗрдВ):
 select P.ID,P.SURNAME from Person P,Person F,Employment E where P.FATHER=F.ID and P.EMPLOYMENT=E.ID and (F.SURNAME<>P.SURNAME or E.Description='US President') and P.MOTHER<>20 


рдирд┐рд░реНрдгрдпред
рдпрд╣ рдбреЗрд▓реНрдлреА 2007 рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдореИрдВ рдПрдХ SQL рдХреНрд╡реЗрд░реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ:
 function GetTestSql: String; var aBulder: TSuperBaseSqlBulder; P: TPersonTable; F: TPersonTable; E: TEmploymentTable; begin aBulder := TSuperBaseSqlBulder.Create; try P := aBulder.AddPersonTable('P'); F := aBulder.AddPersonTable('F'); E := aBulder.AddEmploymentTable('E'); Result := ( (P.Father = F.ID) and (P.Employment = E.ID) and ( (F.Surname <> P.Surname) or (E.Description = 'US President') ) and (P.Mother <> 20) ).Select([P.ID, P.Surname]); finally aBulder.Free; end; end; 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, "рдкрд░рд┐рдгрд╛рдо: =" рдХреЗ рдмрд╛рдж рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ LINQ рдХреЗ рд╕рдорд╛рди рд╣реИред рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЙрд▓рдо рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдЧрд╛, рдЯрд╛рдЗрдк рдЕрд╕рдВрдЧрддрддрд╛ рдХреЛ рдкрдХрдбрд╝реЗрдЧрд╛ред рдпрд╛рдиреА рдХреЛрдИ рднреА рдпрд╛рдж рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:
 E.UnknownFiled = 1 //   E.Description = E.ID //    P.Mother = 'Miss World' //    

рд╣рд░ рдЪреАрдЬ рдХреА рдЦрд╛рддрд┐рд░ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЕрдм GetTestSql рдХреЛ рдкрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдВрдкрд╛рдЗрд▓рд░ рд▓реЗрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЕрдкрдиреЗ рдЖрдзрд╛рд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕рдВрдХрд▓рдХ рдХреЛ рд╕рдордЭрд╛рдирд╛ рд╣реЛрдЧрд╛ред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рдЖрдк рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦреЗрдВрдЧреЗ, рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛:
 uses UKSqlBulder; type TPersonTable = class(TSqlTable) property ID: TCondField_Integer index 0 read GetCondFields_Integer; property Surname: TCondField_String index 1 read GetCondFields_String; property Employment: TCondField_Integer index 2 read GetCondFields_Integer; property Mother: TCondField_Integer index 3 read GetCondFields_Integer; property Father: TCondField_Integer index 4 read GetCondFields_Integer; end; TEmploymentTable = class(TSqlTable) property ID: TCondField_Integer index 0 read GetCondFields_Integer; property Description: TCondField_String index 1 read GetCondFields_String; end; TSuperBaseSqlBulder = class(TSqlBulder) function AddPersonTable(const aAlias: String = ''): TPersonTable; function AddEmploymentTable(const aAlias: String = ''): TEmploymentTable; end; implementation { TSuperBaseSqlBulder } function TSuperBaseSqlBulder.AddPersonTable(const aAlias: String = ''): TPersonTable; begin Result := TPersonTable.Create; Result.Name := 'Person'; Result.Alias := aAlias; Result.Add(TSqlField_Integer.Create('ID')); Result.Add(TSqlField_String.Create('SURNAME')); Result.Add(TSqlField_Integer.Create('EMPLOYMENT')); Result.Add(TSqlField_Integer.Create('MOTHER')); Result.Add(TSqlField_Integer.Create('FATHER')); Add(Result); end; function TSuperBaseSqlBulder.AddEmploymentTable(const aAlias: String = ''): TEmploymentTable; begin Result := TEmploymentTable.Create; Result.Name := 'Employment'; Result.Alias := aAlias; Result.Add(TSqlField_Integer.Create('ID')); Result.Add(TSqlField_String.Create('Description')); Add(Result); end; 


рдФрд░ рдЕрдВрдд рдореЗрдВ, UKSqlBulder рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб:
 unit UKSqlBulder; interface uses Contnrs; type TSqlBulder = class; TSqlTable = class; TSqlField = class; TSqlField_Integer = class; TSqlField_String = class; TRCondition = record private AsSql: String; public class operator LogicalAnd(const A, B: TRCondition): TRCondition; class operator LogicalOr(const A, B: TRCondition): TRCondition; function Select(const aFields: array of TSqlField): String; end; TCondField_Integer = record Field: TSqlField_Integer; class operator Equal(const A, B: TCondField_Integer): TRCondition; class operator NotEqual(const A, B: TCondField_Integer): TRCondition; class operator Equal(const A: TCondField_Integer; const aArg: Integer): TRCondition; class operator NotEqual(const A: TCondField_Integer; const aArg: Integer): TRCondition; class operator Implicit(A: TCondField_Integer): TSqlField; end; TCondField_String = record Field: TSqlField_String; class operator Equal(const A, B: TCondField_String): TRCondition; class operator NotEqual(const A, B: TCondField_String): TRCondition; class operator Equal(const A: TCondField_String; const aArg: String): TRCondition; class operator NotEqual(const A: TCondField_String; const aArg: String): TRCondition; class operator Implicit(A: TCondField_String): TSqlField; end; TSqlBulder = class(TObjectList) private function GetTables(aIndex: Integer): TSqlTable; protected procedure Add(aTable: TSqlTable); public property Tables[aIndex: Integer]: TSqlTable read GetTables; default; end; TSqlField = class Table: TSqlTable; Name: String; function FullName: String; constructor Create(const aName: String); end; TSqlField_Integer = class(TSqlField) end; TSqlField_String = class(TSqlField) // MaxLength: Integer; not used end; TSqlTable = class(TObjectList) private Bulder: TSqlBulder; function GetFields(aIndex: Integer): TSqlField; protected Alias: String; Name: String; function GetCondFields_Integer(aIndex: Integer): TCondField_Integer; function GetCondFields_String(aIndex: Integer): TCondField_String; procedure Add(aField: TSqlField); public property Fields[aIndex: Integer]: TSqlField read GetFields; default; end; implementation uses SysUtils; { TSqlTable } procedure TSqlTable.Add(aField: TSqlField); begin inherited Add(aField); aField.Table := self; end; function TSqlTable.GetFields(aIndex: Integer): TSqlField; begin Result := TSqlField(inherited Items[aIndex]); end; function TSqlTable.GetCondFields_Integer(aIndex: Integer): TCondField_Integer; begin Result.Field := Fields[aIndex] as TSqlField_Integer; end; function TSqlTable.GetCondFields_String(aIndex: Integer): TCondField_String; begin Result.Field := Fields[aIndex] as TSqlField_String; end; { TSqlField } constructor TSqlField.Create(const aName: String); begin inherited Create; Name := aName; end; function TSqlField.FullName: String; begin Result := Table.Alias + '.' + Name; end; { TCondField_Integer } class operator TCondField_Integer.Implicit(A: TCondField_Integer): TSqlField; begin Result := A.Field; end; class operator TCondField_Integer.Equal(const A, B: TCondField_Integer): TRCondition; begin Result.AsSql := A.Field.FullName + '=' + B.Field.FullName; end; class operator TCondField_Integer.NotEqual(const A, B: TCondField_Integer): TRCondition; begin Result.AsSql := A.Field.FullName + '<>' + B.Field.FullName; end; class operator TCondField_Integer.Equal(const A: TCondField_Integer; const aArg: Integer): TRCondition; begin Result.AsSql := A.Field.FullName + '=' + IntToStr(aArg); end; class operator TCondField_Integer.NotEqual(const A: TCondField_Integer; const aArg: Integer): TRCondition; begin Result.AsSql := A.Field.FullName + '<>' + IntToStr(aArg); end; { TCondField_String } class operator TCondField_String.Implicit(A: TCondField_String): TSqlField; begin Result := A.Field; end; class operator TCondField_String.Equal(const A, B: TCondField_String): TRCondition; begin Result.AsSql := A.Field.FullName + '=' + B.Field.FullName; end; class operator TCondField_String.NotEqual(const A, B: TCondField_String): TRCondition; begin Result.AsSql := A.Field.FullName + '<>' + B.Field.FullName; end; class operator TCondField_String.Equal(const A: TCondField_String; const aArg: String): TRCondition; begin Result.AsSql := A.Field.FullName + '=''' + aArg + ''''; end; class operator TCondField_String.NotEqual(const A: TCondField_String; const aArg: String): TRCondition; begin Result.AsSql := A.Field.FullName + '<>''' + aArg + ''''; end; { TRCondition } function TRCondition.Select(const aFields: array of TSqlField): String; var i: Integer; aSelect, aFrom: String; aBulder: TSqlBulder; aTable: TSqlTable; begin if Length(aFields) <= 0 then raise Exception.Create('Invalid argument'); aBulder := aFields[0].Table.Bulder; aFrom := ''; for i := 0 to aBulder.Count - 1 do begin aTable := aBulder[i]; aFrom := aFrom + aTable.Name + ' ' + aTable.Alias + ','; end; aFrom[Length(aFrom)] := ' '; aSelect := ''; for i := 0 to Length(aFields) - 1 do begin aSelect := aSelect + aFields[i].FullName + ','; end; aSelect[Length(aSelect)] := ' '; Result := Format('select %sfrom %swhere %s', [aSelect, aFrom, AsSql]); end; class operator TRCondition.LogicalAnd(const A, B: TRCondition): TRCondition; begin Result.AsSql := A.AsSql + ' and ' + B.AsSql; end; class operator TRCondition.LogicalOr(const A, B: TRCondition): TRCondition; begin Result.AsSql := '(' + A.AsSql + ' or ' + B.AsSql + ')'; end; { TSqlBulder } procedure TSqlBulder.Add(aTable: TSqlTable); var aPrefix: String; begin if aTable.Alias = '' then begin if Count > 0 then aPrefix := 'T' + IntToStr(Count + 1) + '_' else aPrefix := 'T_'; aTable.Alias := aPrefix + aTable.Name; end; aTable.Bulder := self; inherited Add(aTable); end; function TSqlBulder.GetTables(aIndex: Integer): TSqlTable; begin Result := TSqlTable(inherited Items[aIndex]); end; end. 



Source: https://habr.com/ru/post/In203970/


All Articles