我正在使用 Delphi 7 和 Firebird 1.5。
我创建了一个在运行时可能包含某些 null 值的查询。我无法想出如何让 Firebird 接受需要保留为 null 的值的显示 null 值。目前,我正在构建 SQL,以便不包括那些为空的参数,但这很繁琐且容易出错。
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;
目前 在 DB.pas 文件中引发了一个 EDatabaseError "No value for parameter 'ThisValue'" 异常,因此我怀疑这是设计问题而不是 firebird 的问题。
我能将参数设置为 NULL 吗?如果可以,应该如何操作?
(编辑:未明确尝试 .Clear。我选择提到 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:\Database\ZMDDEV12\clinplus');
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.