2013-06-11 10 views
5

Sto tentando di passare un valore null a un parametro TSQLDataset. La query ha il seguente formato:Passaggio del valore NULL in query delphi server SQL parametrizzata

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; 

Il parametro B è annullabile, ma è anche una chiave esterna. Se l'utente inserisce qualcosa in questo campo, allora B deve essere convalidato rispetto ai valori in un'altra tabella. Se è vuoto, voglio che venga ignorato. Stavo passando "", ma questo ovviamente produce un errore di violazione FK.

ho provato:

SQL_dataset.ParamByName('B').Value:=Null; 

..ma tanto sono un "autista dbExpress non supporta il tipo di dati tdbxtypes.unknown" errore.

Ho anche provato:

SQL_dataset.ParamByName('B').DataType:=ftVariant; 
SQL_dataset.ParamByName('B').Value:=Null; 

..ma poi si "dbExpress driver non supporta il tipo di dati tdbxtypes.variant" errore.

Non so cosa sto facendo male, qualsiasi aiuto sarebbe apprezzato. Attualmente sto elaborando un elenco di parametri basato sul fatto che la stringa sia popolata o meno, e questo funziona bene; è solo un po 'goffo (nella mia domanda reale) poiché ci sono alcuni parametri da validare.

Sto usando Delphi XE4 e SQL Server 2012.

Aggiornamento:

Grazie per tutto l'aiuto, i vostri suggerimenti avevano ragione tutti insieme, era qualcos'altro che ha prodotto quel 'autista dbExpress' errore. Stavo creando una lista di parametri 'flessibile', nel tentativo di aggirare il problema, e questo ha causato l'eccezione:

Parameter_string:=''; 

If B<>'' then Parameter_string:='B = :B,' 

Query_text:='MERGE ...' 
      '...' 
      'UPDATE SET A = :A, '+Parameter_string+' C = :C' .... 

... L'idea è che se B è vuota, allora il parametro non sarà ' elencato 'nella query.

Questo non funziona, o la mia implementazione non funziona (non so perché, mi manca ovviamente un passaggio da qualche parte).

Comunque, il codice di lavoro:

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; 

risposta

1

Se ricordo bene, l'equivalente db-null a Delphi è Variants.Null

0

approccio usuale sarebbe utilizzando parametri volta per query e assegnare l'appropriato tipo di dati. Il valore può essere assegnato a 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 [email protected],[email protected] where [email protected]'; 
    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; 
+0

Grazie, ho provato questo, ottenere lo stesso errore come osservato in precedenza nel commento a @ pf1957. Mayve ho qualcos'altro che ha incastrato questo errore? – Alex

+0

Grazie per l'aiuto, vedi aggiornamento. – Alex

2

che dire:

SQL_dataset.ParamByName('B').Clear;

+0

Ho letto questo suggerimento altrove, ma ottengo il "driver dbExpress non supporta il tipo di dati TDBXTypes.UNKNOWN. Errore fornitore": errore quando lo provo. Sto facendo qualcos'altro di sbagliato? – Alex

+0

Strano ...attualmente sto migrando da FIB + a FireDAC e l'ho testato su entrambe le connettività ed è possibile usare Clear o Value: = assegnazione nulla. E mi aspetto che funzioni su ogni set di dati. Almeno non ho mai riscontrato un problema con questo, ma non ho mai usato dbExpress. – pf1957

+0

Grazie ancora, hai ragione, vedi l'aggiornamento sopra. – Alex

Problemi correlati