2013-06-11 40 views
5

Tôi đang cố truyền giá trị null vào tham số TSQLDataset. Truy vấn có dạng:Truyền giá trị NULL vào truy vấn máy chủ SQL delphi được tham số hóa

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; 

Tham số B là vô hiệu, nhưng cũng là khóa ngoài. Nếu người dùng nhập nội dung nào đó vào trường này, thì B phải được xác thực đối với các giá trị trong bảng khác. Nếu nó trống thì tôi muốn nó bị bỏ qua. Tôi đã đi qua '', nhưng điều này rõ ràng là tạo ra một lỗi vi phạm FK.

tôi đã cố gắng:

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

..nhưng sau đó tôi nhận được một "tài xế dbExpress không hỗ trợ kiểu dữ liệu tdbxtypes.unknown" lỗi.

Tôi cũng đã cố gắng:

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

..nhưng sau đó có "tài xế dbExpress không hỗ trợ kiểu dữ liệu tdbxtypes.variant" lỗi.

Không chắc chắn những gì tôi đang làm sai, mọi trợ giúp sẽ được đánh giá cao. Tôi hiện đang vẽ một danh sách tham số dựa trên việc chuỗi có được điền hay không, và điều này hoạt động tốt; nó chỉ là một chút clunky (trong truy vấn thực tế của tôi) vì có khá một vài tham số để xác nhận.

Tôi đang sử dụng Delphi XE4 và SQL Server 2012.

Cập nhật:

Cảm ơn tất cả sự giúp đỡ, góp ý của bạn đã đúng tất cả cùng, nó là cái gì khác mà sản xuất đó là tài xế dbExpress ' lỗi. Tôi đã tạo danh sách tham số 'linh hoạt' trong nỗ lực giải quyết vấn đề của mình và điều này gây ra ngoại lệ:

Parameter_string:=''; 

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

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

... ý tưởng là nếu B là trống thì thông số sẽ không ' được liệt kê 'trong truy vấn.

Điều này không hiệu quả hoặc việc triển khai của tôi không hoạt động (không chắc chắn lý do tại sao, tôi rõ ràng là thiếu một bước nào đó).

Dù sao, mã làm việc:

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; 

Trả lời

1

Nếu tôi nhớ chính xác, tương đương với db-null trong Delphi là Variants.Null

0

cách tiếp cận thông thường sẽ được sử dụng các thông số một lần cho mỗi truy vấn và giao cho thích hợp loại dữ liệu. Giá trị có thể được gán cho 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

Cảm ơn, tôi cố gắng này, nhận được cùng một lỗi như đã nêu ở trên trong bình luận cho @ pf1957. Mayve tôi có cái gì khác đó là casung lỗi này? – Alex

+0

Cảm ơn sự giúp đỡ, xem cập nhật. – Alex

2

gì về:

SQL_dataset.ParamByName('B').Clear;

+0

Tôi đã đọc đề xuất đó ở nơi khác, nhưng tôi nhận được trình điều khiển "dbExpress không hỗ trợ loại dữ liệu TDBXTypes.UNKNOWN. Thông báo lỗi của nhà cung cấp:" lỗi khi tôi thử. Tôi đang làm điều gì khác sai? – Alex

+0

Lạ ...hiện tại tôi đang di chuyển từ FIB + sang FireDAC và tôi đã thử nghiệm nó trên cả hai kết nối và có thể sử dụng lệnh Clear hoặc Value: = null. Và tôi hy vọng rằng nó hoạt động trên mỗi tập dữ liệu. Ít nhất tôi đã không bao giờ gặp một vấn đề với điều này, nhưng tôi không bao giờ được sử dụng dbExpress. – pf1957

+0

Xin cảm ơn một lần nữa, bạn nói đúng, hãy xem cập nhật ở trên. – Alex

Các vấn đề liên quan