【问题标题】:"Could not convert varient of type (Null) into type (OleStr)" using a query component to extract data for later usage“无法将类型(Null)的变体转换为类型(OleStr)”使用查询组件提取数据以供以后使用
【发布时间】:2019-05-14 11:45:12
【问题描述】:

我正在尝试使用 qry1 从表“游戏”中提取数据到一个字符串变量中,然后将其插入到“库”中。我的问题是当我单击按钮时,它在sGameName := qry1['GameName']; 行上给了我上面提到的错误。该字段是一个短字符串变量

procedure TForm1.btnConfirmClick(Sender: TObject);
var
  sGameID, sGameName, sPlatform : string;
begin
  if (chkAddLb.Checked = True) and (chkRemoveLb.Checked = False) then
  begin
    qry1.Close;
    qry1.SQL.Text := 'SELECT * FROM Games WHERE GameName = "' + cbb1.Items.Text + '";';
    qry1.Open;
    qry1.First;
    sGameID := qry1['GameID'];
    sGameName := qry1['GameName'];
    sPlatform := qry1['Platform'];
    qry1.Close;
    qry1.SQL.Text := 'INSERT INTO Library ([GameName],[GameID],[Platform],[UserID]) VALUES ("' + sGameName + '","' + sGameID + '","' + sPlatform + '","' + sLoggedInUser + '");';
    qry1.ExecSQL;
    qry1.SQL.Text := 'SELECT * FROM Library WHERE UserID = "' + sLoggedInUser + '";';
    qry1.Open;
  end;

我希望变量sGameName 被赋予列中的值,但所发生的只是弹出错误。

到目前为止,这只发生在该行。

【问题讨论】:

  • 可能发生的情况是 GameName 列为空,由变体 Null by qry1 表示。逻辑是,由于该列为Null,因此无法转换为字符串,需要在尝试读取其字符串值之前检查该列是否包含Null。

标签: delphi variables variable-assignment


【解决方案1】:

问题

显然这个字段返回null,一般表示它是空的。

null 的变量不能分配给这样的字符串。重现问题而不涉及查询的小代码如下所示:

var
  s: String;
  v: Variant;
begin
  v := null;
  s := v;
  ShowMessage(s);

注意有些数据库(尤其是Oracle),不区分空字符串和null,所以如果你插入一个空字符串,你会得到null,因为对他们来说是一样的。

GameName 是空的,这很奇怪,因为您在 where 子句中使用了它。这可能是因为未找到游戏并且您的查询未返回任何行。在执行其余代码之前检查qry1.IsEmpty 以检查您是否真的得到了结果。那可能已经解决了您的问题...

解决方案

因此,如果您检查了查询是否确实返回了一行,但某些字段实际上是 null 并且您需要处理它,那么有两种可互换的方法来做到这一点:

使用字段的AsString 方法。为此,您需要使用 FieldByName 方法来获取字段对象,而不是它的变量值:

sGameName := qry1.FieldByName('GameName').AsString;

或使用VarToStr 函数。效果是一样的,我认为这或多或少是 AsString 无论如何都在做的事情。使用哪一个是个人喜好问题。

sGameName := VarToStr(qry1['GameName']);

【讨论】:

  • 我刚刚尝试了你的建议,它给出了同样的错误,但是我在显示消息中显示输出后将cbb1.Items.Text 更改为cbb1.Text,导致cbb1 中的每个项目要显示...这就是为什么它没有在qry1['GameName'] 或表中返回任何内容。但令我困扰的是qry1['GameID'] 没有被标记为错误,即使它遇到了与GameName 相同的问题。
  • 关于 Lines.Text 的要点。没看出来那个关于 GameId,也许它是不同的字段类型,行为不同?而且,光标通常会在给出异常的那一行之后,因此您可能需要再次检查(可能使用断点并单步执行)它实际上是哪一行。
  • 是的,有道理。但是该表中的所有字段都是短文本,因此很可能错误会跳到下一行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
相关资源
最近更新 更多