【问题标题】:Firebird exception in Delphi WideStringType OutParameterDelphi WideStringType OutParameter 中的 Firebird 异常
【发布时间】:2012-06-17 23:47:28
【问题描述】:

我有示例 firebird 存储过程

PROCEDURE PROCEDURE01
RETURNS (
 PARAMETER01 VARCHAR(50))
AS 
BEGIN
  PARAMETER01 = 'Hello';
END

在德尔福方面

LCommand := SQLConnection1.DBXConnection.CreateCommand;
LCommand.CommandType := TDBXCommandTypes.DbxStoredProcedure;
LCommand.Text := 'PROCEDURE01';
LIdOut := LCommand.CreateParameter;
LIdOut.ParameterDirection := TDBXParameterDirections.OutParameter;
LIdOut.DataType := TDBXDataTypes.WideStringType;
LIdOut.Name := 'PARAMETER01';
LCommand.Parameters.AddParameter(LIdOut);
LCommand.Prepare;
LReader := LCommand.ExecuteQuery;

并收到异常

“算术异常、数值溢出或字符串截断”

【问题讨论】:

  • WideString 表示多字节字符,您的参数设置为VARCHAR(50),通常是单字节字符。尝试使用兼容的类型。 (你真的用全部大写字母输入所有存储的过程吗?如果是这样,我很高兴我不必使用你的 SQL - 大喊使事情难以阅读。他们发明了 Shift 键是有原因的。)跨度>
  • @Ken White,在 Firebird 中编写大写关键字是常见的做法。我猜这只是一个旧习惯,所以不必大喊大叫。
  • @LightBulb:除了它们不是所有的关键字。 PROCEDURE01 不是关键字,“PARAMETER01”也不是。不需要大写,尤其是在 SQL 和非 SQL 语句之间不可能有歧义的存储过程中。文本,无论是 SQL 语句还是电子邮件或网络帖子中的普通句子,在全部大写时都难以阅读。 :-) 而且我并没有指责海报对我们大喊大叫,而是大喊大叫。 :-)

标签: delphi parameters firebird


【解决方案1】:

这似乎是TDBXCommand(或者可能是 Dbexpress firebird 驱动程序)的限制,因为使用其他类型的输出参数都可以正常工作。作为解决方法,您可以使用 TSQLStoredProc 类。

试试这个示例。

var
 LSQLStoredProc :  TSQLStoredProc;
begin
  LSQLStoredProc:=TSQLStoredProc.Create(nil);
  try
    LSQLStoredProc.SQLConnection:=SQLConnection1;
    LSQLStoredProc.StoredProcName:='PROCEDURE01';
    LSQLStoredProc.ExecProc;
    ShowMessage(LSQLStoredProc.ParamByName('PARAMETER01').AsString);
  finally
    LSQLStoredProc.Free;
  end;
end;

【讨论】:

  • +1 用于提供从代码调用存储过程的“正确”方式。 IMO,OP 使用了一种不常见的方式来做到这一点。
【解决方案2】:

以将数据库设置为 UTF-8 为例。

CREATE DATABASE localhost:mybase
  USER SYSDBA
  PASSWORD masterkey
  PAGE_SIZE 8192
  DEFAULT CHARACTER SET UTF8;
  SET NAMES ISO8859_1;

CREATE TABLE scales (
  ID ...,      
  byteken VARCHAR(50) COLLATE DE_DE,

看看我在Arithmetic exception, numeric overflow, or string truncation的回答

【讨论】:

    【解决方案3】:

    在存储过程中先将“SUSPEND”放在“END”之前

    【讨论】:

    • 我插入了暂停但结果是一样的
    • 暂停需要从存储过程中返回值,那你为什么要取消我的卡马?
    • 我没有投反对票(“否决你的卡玛”),但这可能是因为您的答案中确实没有有用的信息。它要么需要包含更多关于为什么这将是一个解决方案的详细信息,要么应该将其删除并作为评论发布。这不是一个完整的答案,它是 8 个单词,背后没有任何理由或信息。
    • SUSPEND 对于只返回 1 个值的过程不是必需的。这里可能是错误的,因为包含 SUSPEND 的过程与没有的过程不同(一个是可选的,另一个不是)。
    猜你喜欢
    • 1970-01-01
    • 2011-01-06
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多