我有一个查询,我在运行时创建一些值可能为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:\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.
解决方法
Query.ParamByName('ThisValue').DataType := ftString;
您绝对不需要清除参数,因为它已经是NULL.我们怎么知道? IsNull正在返回true …
Use Clear to assign a NULL value to a
parameter.
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”的地方.