开发者

Format a date according to ADO provider

开发者 https://www.devze.com 2023-02-03 22:32 出处:网络
I have a Delphi 2010 application using ADO to support a database that can be either SQL Server or MS Access.When sending SQL to the database using parameterized queries differences in date representat

I have a Delphi 2010 application using ADO to support a database that can be either SQL Server or MS Access. When sending SQL to the database using parameterized queries differences in date representation are handled correctly. But I occasionally have the need to form dynamic SQL and se开发者_JAVA技巧nd that to the database as well.

Is there any way to either have the TADOConnection format my date into a text string appropriate for the current database, or to interrogate the connection to learn how I should format the date? Otherwise I'm stuck building a table of provider names and date formatting functions.


You should be able to use parameters with dynamic sql as well. I have done this in several versions of my own OPF framework.

Just write a SQL statement using parameters, assign that as a string to the SQL text of a TAdoQuery (or TAdoCommand). The component should then parse your text and set up the parameters collections for you. After that you should be able to assign the values to your parameters and call Open or Execute...

To give you an idea:

  DS := DatasetClass.Create( self.Connection );
  try
    DS.QueryText := SQL.Text;
    FillSelectParams( DS );
    DS.Open;
    try
      ...
    finally
      DS.Close;
    end;
  finally
    DS.Free;
  end;

In which the FillSelectParams calls the following FillParams procedure:

procedure TSQLDataManager.FillParams(ADS: TCustomDataset);
var
  i: integer;
  ParamName: string;
  Attr: TCustomDomainAttribute;
  Ref: TCustomDomainObject;
  Value: Variant;
begin
  for i := 0 to ADS.ParamCount - 1 do begin
    Value := Null;
    ParamName := ADS.ParamName[i];
    if ParamName = 'Id' then begin
      ParamName := 'Identity';
    end;
    Attr := CDO.AttrByName[ParamName];
    if Attr <> nil then begin
      Value := ADS.AdjustParamValue( Attr );
    end else begin
      Ref := CDO.ReferenceByName[ParamName];
      if ( Ref <> nil ) and ( Ref.Identity <> C_UnassignedIdentity ) then begin
        Value := Ref.Identity;
      end;
    end;
    if Value <> Null then begin
      ADS.ParamValue[i] := Value;
    end;
  end;
end;

In this case the param values are taken from a custom domain object (CDO), but you can substitute your own flavour here.

The AdjustParamValue function takes care of a couple of conversions. It has been implemented in the ADO version of the TCustomDataSet class descendant used, to take care of component variations with different TDataSet descendants, but nowhere does the SQL database type come into play:

function TADODCDataset.AdjustParamValue(Attr: TCustomDomainAttribute): Variant;
begin
  if Attr is TIdentityAttribute then begin
    if Attr.AsInteger = 0 then begin
      Result := Null;
    end else begin
      Result := Attr.Value;
    end;
  end else if Attr is TBooleanAttribute then begin
    if Attr.AsBoolean then begin
      Result := Integer( -1 );
    end else begin
      Result := Integer( 0 );
    end;
  end else if Attr is TDateTimeAttribute then begin
    if Attr.AsDateTime = 0 then begin
      Result := Null;
    end else begin
      Result := Attr.Value;
    end;
  end else if Attr is TEnumAttribute then begin
    Result := Attr.AsString
  end else begin
    Result := Attr.Value;
  end;
end;


Larry, i will give you an answer for the SQL Server Part.

you can use the sys.syslanguages system view to get information about the languages installed in the sql server, one of the columns returned by this view is called dateformat which indicate the Date order, for example, DMY.

also using the @@langid (which returns the local language identifier (ID) of the language that is currently being used.) function you can write something like this to obtain the current date format used by the Sql Server.

select dateformat from sys.syslanguages  where langid=@@langid

so now you will have a string which you can parse in delphi to format your date.

Another option is pick one of the predefined formats of SQL Server and use the CONVERT function in your SQL sentence for convert the string to the date.

check this sample which uses the ISO format to convert

//The ISO  format is yyyymmdd so i can use the FormatDateTime function to convert any TdateTime to a Iso format sdatetiem string
DateStr:=FormatDateTime('YYYYMMDD',Now);
//Now construct the sql server sentence
SqlSentence:=Format('UPDATE MyTable SET DateField=CONVERT(DATETIME,%s,112)',QuotedStr(DateStr));


Try to use the ODBC date escape sequence, which may be supported by SQL Server and Access OLEDB providers. For example:

{d '2011-01-14'}


As Marjan suggests, you shoud always use parameters. (try searching for SQL-injection)

Another reason to use parameters is that query plans can be reused on the sql server. If the first statement generated is SELECT * from customer where created>'2010-12-21' and the next statetement generated is SELECT * from customer where created>'2010-12-22', the query optimizer/plan gets generated/compiled both times (different statement). But if the statement both times are SELECT * from customer where created>?, the plan is reused -> (slightly) lower presure on SQL server.

I you just wan't a quick and dirty solution all the SQL (implementations) i have tried (I havn't tries Access) can accept and understand the ISO date format (eg. '2010-12-21')

0

精彩评论

暂无评论...
验证码 换一张
取 消