我正在使用Delphi 7和Firebird 1.5.
我有一个在运行时创建的查询,其中一些值可能为null.我无法弄清楚如何让Firebird接受我需要保留为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;
Run Code Online (Sandbox Code Playgroud)
目前在DB.pas中引发了EDatabaseError"参数'ThisValue'''没有值,所以我怀疑这是设计而不是火鸟问题.
我可以将参数设置为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.
Run Code Online (Sandbox Code Playgroud)
Ser*_*yuz 10
错误的原因是'dbx'不知道参数的数据类型.由于永远不会赋值,因此它的数据类型是ftUnknown执行时间,因此是错误.'ParamType'也是一样,但默认情况下假设'ptInput',所以没问题.
Query.ParamByName('ThisValue').DataType := ftString;
Run Code Online (Sandbox Code Playgroud)
你绝对不需要Clear参数,因为它已经存在了NULL.我们怎么知道呢?IsNull正在回归......
使用"清除"为参数指定NULL值.
指示分配给参数的值是否为NULL(空白).
你绝对不需要Bound参数,因为它完全无关紧要.当'Bound'为false时,数据集将尝试从其参数的数据源提供默认值.但是您的数据集甚至没有链接到数据源.从文档:
[...]表示查询和存储过程的数据集使用Bound的值来确定是否为参数指定默认值.如果Bound为false,则表示查询的数据集将尝试从其DataSource属性指示的数据集中分配值.[...]
如果文档不够,请参阅TCustomSQLDataSet.SetParamsFromCursor'sqlexpr.pas'中的代码.它是dbx框架中引用参数"Bound"的唯一位置.
使用 TParam.Clear
Query.ParamByName('ThisValue').Clear;
Run Code Online (Sandbox Code Playgroud)
"使用Clear为参数分配NULL值." (来自文件)
| 归档时间: |
|
| 查看次数: |
20537 次 |
| 最近记录: |