Как использовать TADOQuery.Parameters с целочисленными типами параметров, которые должны быть помещены в два или более мест в запросе? - PullRequest
2 голосов
/ 30 сентября 2011

У меня сложный запрос, который содержит более одного места, где необходимо заменить одно и то же значение первичного ключа. Это выглядит так:

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

Эти простые случаи работают нормально. Компонент TADOQuery, и он работает нормально, пока вы не добавите :parameters в строку SQL.

Обновление: когда я использую следующий код во время выполнения, подстановка параметров фактически выполняется (обходится некоторая ошибка в компонентах ADO) и появляется другая ошибка:

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

Теперь ошибка меняется на:

Incorrect syntax near the keyword 'inner''.

Обратите внимание, что эта ошибка исчезнет, ​​если я просто перестану использовать функцию подстановки параметров.

Update2: Принятый ответ предполагает, что мне нужно найти две разные копии параметра с одним и тем же именем, что беспокоило меня, поэтому я переработал запрос следующим образом:

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

Затем я использовал @aVar в скрипте, где это было необходимо, чтобы избежать повторного использования :aBaitId. (Если количество раз, когда значение параметра используется, изменяется, мне не нужно искать все параметры, соответствующие имени, и заменять их).

Полагаю, что вспомогательная функция тоже подойдет: SetAllParamsNamed(aQuery:TAdoQuery; aName:String;aValue:Variant)

1 Ответ

2 голосов
/ 30 сентября 2011

FindParam находит только один параметр, в то время как у вас есть два с тем же именем. Набор данных Delphi добавляет каждый параметр как отдельный к своему набору параметров.

Это должно работать, если вы перебираете все параметры, проверяете, совпадает ли имя, и устанавливаете значение каждого из них, хотя обычно я выбираю для каждого параметра следующий номер для между ними.

...