gpt4 book ai didi

delphi - 如何使用 Delphi 7 ADOQuery.ExecSQL 更新 SQL Server 上的 DateTime 并保留毫秒?

转载 作者:行者123 更新时间:2023-12-03 14:48:24 31 4
gpt4 key购买 nike

如何使用 Delphi 7 ADOQuery.ExecSQL 更新 SQL Server 2012 上的 DateTime 并保留毫秒?

SQL Server 似乎降低了秒精度,因此我在 SQL Server 2012 DateTime2[7] 字段上没有毫秒或微秒。 MS Access 不会通过此 ADO 查询减少毫秒数。以下 ADOQuery 代码似乎适用于我关心的所有数据类型(SQL Server DateTime 除外)。

我使用的连接字符串是:Provider=SQLNCLI11.1;集成安全性=SSPI;用户 ID="";初始文件名="";服务器 SPN="";数据源=myPC\SQLSERVER2012EXP;初始目录=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;

已更新

修改了 MS Access 和 SQL Server 的代码:

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;

最佳答案

通过 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;

使用 then 以下将导致四舍五入:

  Adoquery1.Parameters.ParamByName('DT').DataType := ftDateTime;
Adoquery1.Parameters.ParamByName('DT').Value := dt;

关于delphi - 如何使用 Delphi 7 ADOQuery.ExecSQL 更新 SQL Server 上的 DateTime 并保留毫秒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14282802/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com