Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 将空值传递到参数化delphi SQL server查询_Sql Server_Delphi_Delphi Xe4_Parameterized Query - Fatal编程技术网

Sql server 将空值传递到参数化delphi SQL server查询

Sql server 将空值传递到参数化delphi SQL server查询,sql-server,delphi,delphi-xe4,parameterized-query,Sql Server,Delphi,Delphi Xe4,Parameterized Query,我正在尝试将空值传递给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

我正在尝试将空值传递给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'',则参数_字符串:='B=:B,'
查询文本:='MERGE…'
'...'
'更新集A=:A',+参数_字符串+'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;
Query\u text:='MERGE…'
'...'
'更新集A=:A,B=:B,C=:C'。。。。
SQL_dataset.CommandType:=ctQuery;
SQL_dataset.CommandText:=查询_文本;
如果B是“”,那么
开始
SQL_dataset.ParamByName('B')。关联字符串:='B';
结束
其他的
开始
SQL_dataset.ParamByName('B')。数据类型:=ftString;
SQL_dataset.ParamByName('B')。值:=Null;
结束;

如果我没记错的话,Delphi中的db null等价物是Variants。null

通常的方法是每个查询使用一次参数并分配适当的数据类型。 值可以指定为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;
那么:


SQL_dataset.ParamByName('B')。清除

我在其他地方读到了该建议,但我得到了“dbExpress驱动程序不支持TDBXTypes.UNKNOWN数据类型。供应商错误消息:”尝试此操作时出错。我做错什么了吗?奇怪。。。目前,我正在从FIB+迁移到FireDAC,并在两个连接性上对其进行了测试,可以使用Clear或Value:=null赋值。我希望它能在每个数据集上工作。至少我从来没有遇到过这个问题,但我从来没有使用过dbExpress。谢谢,我尝试过这个,得到了上面在@pf1957评论中提到的相同错误。可能是我有别的原因导致了这个错误?