2

同じ主キー値を置換する必要がある複数の場所を含む複雑なクエリがあります。次のようになります。

select  Foo.Id,
        Foo.BearBaitId,
        Foo.LinkType,
        Foo.BugId,
        Foo.GooNum,
        Foo.WorkOrderId,
        (case when Goo.ZenID is null or Goo.ZenID=0 then
            IsNull(dbo.EmptyToNull(Bar.FanName),dbo.EmptyToNull(Bar.BazName))+' '+Bar.Strength else
            '@'+BarZen.Description end) as Description,
        Foo.Init,
        Foo.DateCreated,
        Foo.DateChanged,
        Bug.LastName,
        Bug.FirstName,
        Goo.BarID,
        (case when Goo.ZenID is null or Goo.ZenID=0 then
             IsNull(dbo.EmptyToNull(Bar.BazName),dbo.EmptyToNull(Bar.FanName))+' '+Bar.Strength else
             '@'+BarZen.Description end) as BazName,
        GooTracking.Status as GooTrackingStatus
  from
    Foo
  inner join Bug on (Foo.BugId=Bug.Id)
  inner join Goo on (Foo.GooNum=Goo.GooNum)
  left join Bar on (Bar.Id=Goo.BarID)
  left join BarZen on (Goo.ZenID=BarZen.ID)
  inner join  GooTracking on(Goo.GooNum=GooTracking.GooNum )
 where (BearBaitId = :aBaitid) 
UNION
 select Foo.Id,
        Foo.BearBaitId,
        Foo.LinkType,
        Foo.BugId,
        Foo.GooNum,
        Foo.WorkOrderId,
        Foo.Description,
        Foo.Init,
        Foo.DateCreated,
        Foo.DateChanged,
        Bug.LastName,
        Bug.FirstName,
        0,
        NULL,
        0
 from Foo
 inner join Bug on (Foo.BugId=Bug.Id)
  where (LinkType=0)  and (BearBaitId= :aBaitid ) 
order by BearBaitId,LinkType desc, GooNum

この重要なクエリで整数パラメータを使用しようとすると、不可能に思えます。次のエラーが表示されます。

Error

Incorrect syntax near ':'.

を取り出して:aBaitid リテラルに置き換えると、クエリは正常に機能します1

上記のクエリに対して他にできることはありますか? 次のような簡単なテストでテストすると:

select * from foo where id = :anid

これらの単純なケースは問題なく機能します。コンポーネントはであり、SQL 文字列にTADOQuery追加するまで正常に動作します。:parameters

更新:実行時に次のコードを使用すると、パラメーターの置換が実際に行われ (ADO コンポーネントの不具合が回避されます)、別のエラーが表示されます。

adoFooContentQuery.Parameters.FindParam('aBaitId').Value := 1;
adoFooContentQuery.Active := true;

エラーは次のように変わります。

Incorrect syntax near the keyword 'inner''.

パラメーター置換機能の使用を単に停止すると、このエラーはなくなることに注意してください。

Update2:受け入れられた回答は、同じ名前のパラメーターの2つの異なるコピーを見つける必要があることを示唆しているため、気になったので、次のようにクエリを作り直しました。

 DECLARE @aVar int;
 SET @aVar = :aBaitid;
 SELECT ....(long query here)

次に、必要に応じてスクリプト全体で @aVar を使用し、:aBaitId. (パラメーター値が使用される回数が変化した場合、名前に一致するすべてのパラメーターを見つけてそれらを置き換える必要はありません)。

このようなヘルパー関数も問題ないと思います。 SetAllParamsNamed(aQuery:TAdoQuery; aName:String;aValue:Variant)

4

1 に答える 1

2

同じ名前のパラメーターが 2 つあるのに対し、FindParam は 1 つのパラメーターしか検出しません。Delphi データセットは、各パラメータを個別のパラメータとしてパラメータのコレクションに追加します。

すべてのパラメーターをループし、名前が一致するかどうかを確認し、一致する各パラメーターの値を設定すると機能するはずですが、通常、同じパラメーターごとにフォローアップ番号を付けてそれらを区別することを選択します。

于 2011-09-30T17:43:37.563 に答える