【发布时间】:2011-09-15 04:22:47
【问题描述】:
我使用的是 Delphi 7 和 Firebird 1.5。
我有一个在运行时创建的查询,其中一些值可能为空。我无法弄清楚如何让 Firebird 接受我需要保留为空的值的显式空值。在这个阶段,我正在构建 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;
目前在 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.
【问题讨论】:
-
@moz,你使用哪些组件来执行sql语句?
-
SQlExpr.pas 中抛出此问题的行是对检查“if iFldType = fldUNKNOWN then”的响应,但设置 .DataType := ftInteger 会给出 Firebird ISC ERROR CODE:335544347 - 验证错误.
-
@moz,显然你在 dbexpress 中遇到了一个错误。谷歌搜索实际上发现了一个类似的 SQL server QC,以及与各种数据类型相关的其他几个相似的错误。有些应该通过对 Delphi 2010 的更新来修复(我在这里使用 D2010 并遇到相同的错误,当我到达办公室时将能够在 XE 上进行测试)。
NULL一直为我工作,但我使用Interbase Express组件(即使是那些不支持 Firebird 的组件)。 -
@Cosmin Prund:发现这一点非常重要,这非常令人放心。现在,如果我们能改变我们使用的连接组件就好了:(
-
@moz 你不应该仅仅为了接受而接受答案。它解决了你的问题吗?如果不是,请不要接受:发布更新结果,获得更多答案。这样,社区获得知识,您最终将解决您的问题。即使您要发布最终答案。