gpt4 book ai didi

sql-server - 当 BCD 映射规则处于事件状态时,在 INSERT 查询中转换参数值会导致算术溢出

转载 作者:行者123 更新时间:2023-12-03 15:57:38 31 4
gpt4 key购买 nike

考虑 MSSQL 数据库中的此表:

CREATE TABLE dbo.TESTPAR
(
ID INTEGER NOT NULL,
YR VARCHAR(50) NULL
)

我有一个带有命令文本的 TFDQuery:

insert into TESTPAR
(ID,YR)
values(:ID,cast(:YR as varchar(4)))

它有两个 ftInteger ptInput 参数

使用

执行它
procedure TFrmCastAsVarchar.BtnTestInsertClick(Sender: TObject);
begin
Inc(FLastID);
FDQuery2.Params[0].AsInteger := FLastID;
FDQuery2.Params[1].AsInteger := 2018;
try
FDQuery2.ExecSQL;
except
on E:Exception do ShowMessage(E.Message);
end;
end;

当 dtBCD 和 dtFmtBCD 字段的映射处于事件状态时,出现错误 EMSSQLNativeException 算术溢出将数字转换为数据类型 varchar:

procedure TDM.SetBCDMapRules;
// For (Fmt)BCD data types. Called from SetOracleMapRules/SetMSSQLMapRules
begin
with FDConnection.FormatOptions.MapRules.Add do
begin // Convert numeric data types with scale=0 and precision<=10 to a 32-bit integer
PrecMax := 10;
PrecMin := 0;
ScaleMax := 0;
ScaleMin := 0;
SourceDataType := dtBCD;
TargetDataType := dtInt32;
end;
with FDConnection.FormatOptions.MapRules.Add do
begin // Do the same for those that might return as dtFmtBCD instead of dtBCD
PrecMax := 10;
PrecMin := 0;
ScaleMax := 0;
ScaleMin := 0;
SourceDataType := dtFmtBCD;
TargetDataType := dtInt32;
end;
with FDConnection.FormatOptions.MapRules.Add do
begin // Convert numeric data types with scale=0 and precision>10 to a 64-bit integer
PrecMin := 11;
ScaleMax := 0;
ScaleMin := 0;
SourceDataType := dtBCD;
TargetDataType := dtInt64;
end;
with FDConnection.FormatOptions.MapRules.Add do
begin // Idem dtFmtBCD
PrecMin := 11;
ScaleMax := 0;
ScaleMin := 0;
SourceDataType := dtFmtBCD;
TargetDataType := dtInt64;
end;
with FDConnection.FormatOptions.MapRules.Add do
begin // All other dtBCD types (notably scale <> 0) should return as float
SourceDataType := dtBCD;
TargetDataType := dtDouble;
end;
with FDConnection.FormatOptions.MapRules.Add do
begin // Idem dtFmtBCD
SourceDataType := dtFmtBCD;
TargetDataType := dtDouble;
end;
end;

(如何)我可以更改 SQL 来解决此问题吗?
或者,我的映射规则中是否存在可以修复的奇怪内容?我很惊讶这竟然有影响。

  • 这当然只是一个基本示例。真实的脚本将其他字符串连接到cast()以得到一个varchar值并放入varchar字段中。
  • 使用 BCD 映射会产生其他问题(例如 DECIMAL 字段类型)。
  • 更改客户端的表结构“不是最佳选择”;-)
  • 我使用许多不同的 ODBC/ native 驱动程序对此进行了测试。
  • 这是 Win7 上的 Delphi Tokyo 10.2.3、W​​in32 应用程序。

最佳答案

当然,您的映射有问题(我们一直在before)。对于参数来说,就是目标到源的转换。 Data Type Mapping主题是这样说的:

In case of a command parameter, the rule defines a transformation of a target data type, specified by an application, into a source data type, supported by a driver.

因此,在本例中,您已指示 FireDAC 将 32 位整数转换为十进制数,当到达 DBMS 时,其长度将不仅仅是 4 个字符。如果您想解决此问题,则(按可靠性排序):

  • 在表格中使用正确的数据类型
  • 停止使用一般映射规则
  • 使用正确的参数数据类型并按实际情况传递值(因此是字符串,而不是整数)
  • 将参数值转换为整数,例如CAST(CAST(:YR AS INTEGER) AS VARCHAR(4))

关于sql-server - 当 BCD 映射规则处于事件状态时,在 INSERT 查询中转换参数值会导致算术溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50257059/

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