9

Delphi7を使用してミリ秒を維持するSQLServer2012のDateTimeをどのように更新しますADOQuery.ExecSQLか?

SQL Serverは秒の精度を落としているように見えるので、SQLServer2012DateTime2[7]フィールドにミリ秒またはマイクロ秒がありません。MS Accessは、このADOクエリでミリ秒をドロップしません。次のADOQueryコードは、SQLServerを除くすべてのDataTypeで機能するようDateTimeです。

私が使用している接続文字列は次のとおりです。 Provider=SQLNCLI11.1;Integrated Security=SSPI;User ID="";Initial File Name="";Server SPN="";Data Source=myPC\SQLSERVER2012EXP;Initial Catalog=MyDatabase

これが私のコードです:

function ExecuteNonQry(Conn:TADOConnection;Sql:string;Params:Variant): Integer;
{ Execute a query that does not return a recordset.  Returns number of rows 
  affected. Params can be any unique name, they are all dealt with in order
  of appearance in the parameter array and in the sql string.
  E.g. SQL 
    'INSERT INTO customers (id,name,country) VALUES (:id,:name,:country)';
  E.g. calling code:
    sql := 
     'INSERT INTO Sessions (SessionType_cod , HasErrors, Start_Timestamp) ' + 
     ' VALUES (:1, :2, :3)';
    params := VarArrayOf([ 1, true, Now ]);
    ExecuteNonQry( GvConnection1, sql, params );

    Note: Do not use ADO with Paradox - will be slow and possibly error prone.

    Tested the following DataTypes with "Insert Into" and "Update" queries
    **********************************************************************
    Delphi          MS Access    SQL Server      Paradox
    -----------------------------------------------------
    ftInteger       Long         int
    ftString        Text(255)    nvarchar(255)
    ftString        Memo         nvarchar(max)
    ftBoolean       Boolean      bit
    ftDateTime      Date         datetime2(7)
    ftDouble        Double       float
}
var
  qry : TADOQuery;
begin
  assert( Conn <> nil);
  assert( Sql <> '');
  qry := TADOQuery.Create(nil);
  qry.DisableControls;
  qry.SQL.Text := Sql;
  AddParametersToQuery(qry, Params);
  qry.Connection := Conn;
  result := qry.ExecSQL;
end;

procedure AddParametersToQuery(var Qry: TADOQuery; Params: Variant);
{ Version 1b.  (Uses Delphi function to replace "DIRegEx" dependencies)
  Add parameters (type and value) to ADO query. ADOQuery must have SQL 
  text set and Params is a variant array. 
  Limitations: SQL Server drops DateTime second precision digits for 
  milliseconds or microseconds.
  E.g. Sql: 
    'INSERT INTO Sessions (SessionType_cod , HasErrors, Start_Timestamp) 
     VALUES (:1, :2, :3)';
  or  Sql: 
    'INSERT INTO Sessions (SessionType_cod , HasErrors, Start_Timestamp) 
     VALUES (:mykey, :HasErrors, :myDateTime)';
}
const
  regPattern = ':';
var
  str: String;
  val: Variant;
  i: Integer;
  sl: TStrings;
begin
  assert( Qry.SQL.Text <> '');

  // in some cases this is necessary.
  Qry.Parameters.ParseSQL(Qry.SQL.Text, true);        

  sl := TStringList.Create;
  try
    // find all param wordssql text such as '1, 2, 3'
    sl := ExtractWordsToStrings(':', Qry.SQL.Text);   

    // loop through any matches found
    for i := 0 to sl.Count -1 do            
    begin
      str := sl[i];
      val := GetVarParam(i, Params);
      // in some cases this is necessary.
      Qry.Parameters.ParamByName(str).DataType := 
          VarTypeToDataType(Ord(VarType(val)) );
      Qry.Parameters.ParamByName(str).Value := val;
    end;
  finally
    sl.Free;
  end;
end;

更新しました

MSAccessおよびSQLServerの変更されたコード:

if (VarType(val) = varDate) And IsSqlServerProvider(Conn.Provider) then begin
  // needed for SQL Server
  Qry.Parameters.ParamByName(str).Value := 
     FormatDateTime('yyyymmdd hh:nn:ss.zzz', val)   
end
else
begin
  // in some cases this is necessary.
  Qry.Parameters.ParamByName(str).DataType := 
     VarTypeToDataType(Ord(VarType(val))); 
  Qry.Parameters.ParamByName(str).Value := val;
end;
4

1 に答える 1

7

Ado 経由の DateTime2(7) は TWideStringField として表示されます。
日時は TDateTimeField として表示されます。
TDatetime を割り当てると、DateTimeToStr(dt) のようにミリ秒が無視される場合の内部変換。
これは、WideString への独自の変換を使用して処理できます。

Function MyDateTimeString(d:TDateTime):String;
begin
  Result := FormatDateTime('yyyymmdd hh:nn:ss.zzz',d);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
dt:TdateTime;
begin
  dt := now;
  Caption := FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz',dt);
  Adoquery1.Paramcheck := true;
  Adoquery1.SQL.Text := 'Insert into Tab (a,b,DT) Values (:a,:b,:DT)';
  Adoquery1.Parameters.ParseSQL(Adoquery1.SQL.Text,true);
  Adoquery1.Parameters.ParamByName('a').Value := 1;
  Adoquery1.Parameters.ParamByName('b').Value := 2;
  Adoquery1.Parameters.ParamByName('DT').Value := MyDateTimeString(dt);
  Adoquery1.ExecSQL;
end;

次に使用すると、丸めが行われます。

  Adoquery1.Parameters.ParamByName('DT').DataType := ftDateTime;
  Adoquery1.Parameters.ParamByName('DT').Value := dt;
于 2013-01-12T07:54:04.753 に答える