Delphi 2007 で作成され、まだ BDE を使用しているレガシー アプリケーションがあります (はい、ADO に切り替える必要がありますが、50 万行を超えるため、これは大きな仕事です)。SQL SERVER ODBC 接続を使用して SQL Server 2008 DB に接続します。代わりに SQL Server Native Client 10.0 に切り替えようとしていて、興味深い問題に遭遇しました。日時フィールドを含むテーブルにレコードを挿入しようとすると、次のエラーが発生します。
Project DateTimeParamTest.exe raised exception class EDBEngineError with message 'General SQL error.
[Microsoft][SQL Server Native Client 10.0]Datetime field overflow. Fractional second precision exceeds the scale specified in
the parameter binding.'.
いくつかの調査を行っているときに、TParameter オブジェクトの NumericScale、Precision、および Size パラメータを操作するコメントを見てきました。TADOQuery は自動的にパラメーターをそれぞれ 3、23、16 に設定し、挿入に問題はありません。TQuery オブジェクトでパラメーターを同じに設定すると、上記と同じエラーが発生します。
誰もこれについて経験があり、簡単な回避策を知っていますか? 試してみたい方のために、次のサンプル コードを作成しました。接続と SQL コードを変更するだけです。
DateTimeParamTest_Main.dfm:
object Form10: TForm10
Left = 0
Top = 0
Caption = 'Form10'
ClientHeight = 111
ClientWidth = 181
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button2: TButton
Left = 20
Top = 16
Width = 75
Height = 25
Caption = 'BDE'
TabOrder = 0
OnClick = Button2Click
end
object dbPMbde: TDatabase
AliasName = 'PMTest'
DatabaseName = 'DB'
LoginPrompt = False
SessionName = 'Default'
Left = 20
Top = 52
end
object qryBDE: TQuery
DatabaseName = 'DB'
SQL.Strings = (
'INSERT INTO TRAN_DETAIL (ID, STARTDATE, ENDDATE)'
'VALUES (:ID, :STARTDATE, :ENDDATE);')
Left = 88
Top = 52
ParamData = <
item
DataType = ftInteger
Name = 'ID'
ParamType = ptInput
end
item
DataType = ftDateTime
Precision = 23
NumericScale = 3
Name = 'STARTDATE'
ParamType = ptInput
Size = 16
end
item
DataType = ftDateTime
Precision = 23
NumericScale = 3
Name = 'ENDDATE'
ParamType = ptInput
Size = 16
end>
end
end
DateTimeParamTest_Main.pas:
unit DateTimeParamTest_Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, DBTables;
type
TForm10 = class(TForm)
Button2: TButton;
dbPMbde: TDatabase;
qryBDE: TQuery;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form10: TForm10;
implementation
{$R *.dfm}
procedure TForm10.Button2Click(Sender: TObject);
begin
dbPMbde.Open;
with qryBDE do
begin
parambyname('ID').Value := 99999999;
parambyname('StartDate').Value := now;
parambyname('EndDate').Value := now;
execsql;
end;
dbPMbde.Close;
end;
end.