我正在尝试将空值传递给TSQLDataset参数。查询的格式为:
Query_text:='MERGE INTO [Table]
USING (VALUES (:A,:B)) AS Source (Source_A, Source_B)
....
WHEN MATCHED THEN
UPDATE SET A = :A
WHEN NOT MATCHED THEN
INSERT(A, B) VALUES (:A,:B);
SQL_dataset.CommandType:=ctQuery;
SQL_dataset.CommandText:=Query_text;
SQL_dataset.ParamByName('A').AsString:='A';
SQL_dataset.ParamByName('B').AsString:={ COULD BE NULL, OR A STRING };
SQL_dataset.ExecSQL;
参数B可以为空,但也是外键。如果用户在此字段中输入内容,则必须根据另一个表中的值验证B.如果它是空白,那么我希望它被忽略。我正在传递'',但这显然会产生FK违规错误。
我试过了:
SQL_dataset.ParamByName('B').Value:=Null;
..但后来我得到一个“dbexpress驱动程序不支持tdbxtypes.unknown数据类型”错误。
我也尝试过:
SQL_dataset.ParamByName('B').DataType:=ftVariant;
SQL_dataset.ParamByName('B').Value:=Null;
..但后来得到“dbexpress驱动程序不支持tdbxtypes.variant数据类型”错误。
不确定我做错了什么,任何帮助都将不胜感激。我目前正在根据字符串是否填充来绘制参数列表,这样做效果很好;它只是有点笨拙(在我的实际查询中),因为有很多参数需要验证。
我正在使用Delphi XE4和SQL Server 2012。
更新
感谢所有的帮助,你的建议一直都是正确的,这是产生'dbexpress驱动'错误的其他因素。为了解决我的问题,我正在创建一个“灵活的”参数列表,这导致了异常:
Parameter_string:='';
If B<>'' then Parameter_string:='B = :B,'
Query_text:='MERGE ...'
'...'
'UPDATE SET A = :A, '+Parameter_string+' C = :C' ....
......这个想法是,如果B为空,那么参数将不会在查询中“列出”。
这不起作用,或者我的实现不起作用(不知道为什么,我显然在某个地方错过了一步)。
无论如何,工作代码:
Query_text:='MERGE ...'
'...'
'UPDATE SET A = :A, B = :B, C = :C' ....
SQL_dataset.CommandType:=ctQuery;
SQL_dataset.CommandText:=Query_text;
If B<>'' then
begin
SQL_dataset.ParamByName('B').AsString:='B';
end
else
begin
SQL_dataset.ParamByName('B').DataType:=ftString;
SQL_dataset.ParamByName('B').Value:=Null;
end;
答案 0 :(得分:2)
怎么样:
SQL_dataset.ParamByName('B').Clear;
答案 1 :(得分:1)
如果我没记错的话,Delphi中的db-null等价物是Variants.Null
答案 2 :(得分:0)
通常的方法是每个查询使用一次参数并分配适当的数据类型。 值可以指定为NULL。
var
Query_text:String;
begin
Query_text:='Declare @A varchar(100) ' // or e.g. integer
+#13#10'Declare @B varchar(100)'
+#13#10'Select @A=:A'
+#13#10'Select @B=:B'
+#13#10'Update Adressen Set Vorname=@A,Strasse=@B where Name=@B';
SQL_dataset.CommandType := ctQuery;
SQL_dataset.CommandText := Query_text;
SQL_dataset.Params.ParseSQL(SQL_dataset.CommandText,true);
Showmessage(IntToStr(SQL_dataset.Params.Count));
SQL_dataset.ParamByName('B').DataType := ftString;
SQL_dataset.ParamByName('B').Value := 'MyText';
SQL_dataset.ParamByName('A').DataType := ftString; // or e.g. ftInteger
SQL_dataset.ParamByName('A').Value := NULL;
SQL_dataset.ExecSQL;
end;