加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何显式插入空值到参数化查询?

发布时间:2020-12-15 10:09:48 所属栏目:大数据 来源:网络整理
导读:我使用的是Delphi 7和Firebird 1.5. 我有一个查询,我在运行时创建一些值可能为null.我不知道如何让Firebird接受明确的null值,我需要离开为null.在这个阶段我正在构建SQL,以便我不包括null的参数,但这是冗长乏味且容易出错的. var Qry: TSQLQuery;begin SetCo
我使用的是Delphi 7和Firebird 1.5.

我有一个查询,我在运行时创建一些值可能为null.我不知道如何让Firebird接受明确的null值,我需要离开为null.在这个阶段我正在构建SQL,以便我不包括null的参数,但这是冗长乏味且容易出错的.

var
  Qry: TSQLQuery;
begin
  SetConnection(Query); // sets the TSQLConnection property to a live database connection
  Query.SQL.Text := 'INSERT INTO SomeTable (ThisColumn) VALUES (:ThisValue)';
  Query.ParamByName('ThisValue').IsNull := true; // read only,true by default
  Query.ParamByName('ThisValue').Clear; // does not fix the problem
  Query.ParamByName('ThisValue').IsNull = true; // still true
  Query.ParamByName('ThisValue').Bound := true; // does not fix the problem
  Query.ExecSQL;

目前一个EDatabaseError“在DB.pas中引发了参数”ThisValue“”“的值,所以我怀疑这是通过设计而不是Firebird问题.

可以将参数设置为NULL吗?如果是这样,怎么办?

(编辑:对不起,没有明确的尝试.清除之前,我留下来,赞成提到IsNull.已经添加声明和更多的代码)

对不起,还有一件事:表上没有“NOT NULL”约束.我不认为这是远远的,但是以为我应该说.

完整的控制台应用程序显示问题在我的结束:

program InsertNull;

{$APPTYPE CONSOLE}

uses
  DB,SQLExpr,Variants,SysUtils;

var
  SQLConnection1: TSQLConnection;
  Query: TSQLQuery;
begin
  SQLConnection1 := TSQLConnection.Create(nil);

  with SQLConnection1 do
  begin
    Name := 'SQLConnection1';
    DriverName := 'Interbase';
    GetDriverFunc := 'getSQLDriverINTERBASE';
    LibraryName := 'dbexpint.dll';
    LoginPrompt := False;
    Params.clear;
    Params.Add('Database=D:DatabaseZMDDEV12clinplus');
    Params.Add('RoleName=RoleName');

    //REDACTED Params.Add('User_Name=');
    //REDACTED Params.Add('Password=');

    Params.Add('ServerCharSet=');
    Params.Add('SQLDialect=1');
    Params.Add('BlobSize=-1');
    Params.Add('CommitRetain=False');
    Params.Add('WaitOnLocks=True');
    Params.Add('ErrorResourceFile=');
    Params.Add('LocaleCode=0000');
    Params.Add('Interbase TransIsolation=ReadCommited');
    Params.Add('Trim Char=False');
    VendorLib := 'gds32.dll';
    Connected := True;
  end;
  SQLConnection1.Connected;
  Query := TSQLQuery.Create(nil);
  Query.SQLConnection := SQLConnection1;
  Query.Sql.Text := 'INSERT INTO crs_edocument (EDOC_ID,LINKAGE_TYPE) VALUES (999327,:ThisValue)';
  //Query.ParamByName('ThisValue').IsNull := true; // read only,true by default
//  Query.ParamByName('ThisValue').Value := NULL;
  Query.ParamByName('ThisValue').clear; // does not fix the problem
  Query.ParamByName('ThisValue').Bound := True; // does not fix the problem
//  Query.ParamByName('ThisValue').IsNull; // still true
  Query.ExecSQL;
end.

解决方法

错误的原因是“dbx”不知道参数的数据类型.由于从未分配值,因此在执行时间内数据类型为ftUnknown,因此出现错误. “ParamType”相同,但默认情况下假定为“ptInput”,所以没有问题.
Query.ParamByName('ThisValue').DataType := ftString;

您绝对不需要清除参数,因为它已经是NULL.我们怎么知道? IsNull正在返回true …

从TParam.Clear Method:

Use Clear to assign a NULL value to a
parameter.

从TParam.IsNull Property:

Indicates whether the value assigned
to the parameter is NULL (blank).

您绝对不需要绑定参数,因为它完全不相关.当“Bound”为false时,数据集将尝试从该参数的数据源中提供默认值.但是您的数据集甚至没有链接到数据源.从documentation:

[…] Datasets that represent queries
and stored procedures use the value of
Bound to determine whether to assign a
default value for the parameter. If
Bound is false,datasets that
represent queries attempt to assign a
value from the dataset indicated by
their DataSource property. […]

如果文档不够,请参阅“sqlexpr.pas”中TCustomSQLDataSet.SetParamsFromCursor中的代码.它是dbx框架中唯一引用参数的“Bound”的地方.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读