Хорошо, так что я сам попробую.
(defun format-fact (stream arg colonp atsignp &rest args)
(destructuring-bind (n acc) arg
(format stream
"~[~A~:;~*~/format-fact/~]"
(1- n)
acc
(list (1- n) (* acc n)))))
(defun fact (n)
(parse-integer (format nil "~/format-fact/" (list n 1))))
Должна быть более приятная и неясная реализация на основе FORMAT. Этот довольно простой и скучный, просто используя FORMAT в качестве замены IF. Очевидно, я не эксперт ФОРМАТ.
В итоге я использовал глобальную временную таблицу в Firebird, сначала вставляя значения параметров, а для получения результатов я использую обычный JOIN
вместо WHERE ... Пункт IN
. Временная таблица зависит от транзакции и очищается при фиксации ( ON COMMIT DELETE ROWS
).
Возможно, вам стоит записать это так:
SELECT * FROM MATABLE
WHERE MT_ID IN (:MYPARAM1 , :MYPARAM2)
Я не думаю, что это можно сделать. Есть ли какая-то конкретная причина, по которой вы не хотите создавать запрос самостоятельно?
I ' Я использовал этот метод пару раз, но он не использует параметры. Он использует список строк и свойство DelimitedText. Вы создаете IDList и заполняете его своими идентификаторами.
Query.SQL.Add(Format('MT_ID IN (%s)', [IDList.DelimitedText]));
Вам также может быть интересно прочитать следующее:
http://www.sommarskog.se/dynamic_sql.html
и
http: //www.sommarskog .se / array-in-sql-2005.html
Охватывает динамический sql с предложениями 'in' и всеми видами. Очень интересно.
Ответ от Юриша - решение в двух из трех случаев:
Но если вы хотите иметь произвольное количество элементов, а иногда и вовсе без элементов, тогда вы можете сгенерировать Заявление SLQ на лету. Использование формата помогает.
Если вы используете Oracle, вам следует обязательно ознакомьтесь с сообщением в блоге Тома Кайта именно по этой теме ( ссылка ).
Следуя указаниям г-на Кайта, вот пример:
SELECT *
FROM MATABLE
WHERE MT_ID IN
(SELECT TRIM(substr(text, instr(text, sep, 1, LEVEL) + 1,
instr(text, sep, 1, LEVEL + 1) -
instr(text, sep, 1, LEVEL) - 1)) AS token
FROM (SELECT sep, sep || :myparam || sep AS text
FROM (SELECT ',' AS sep
FROM dual))
CONNECT BY LEVEL <= length(text) - length(REPLACE(text, sep, '')) - 1)
Где вы должны привязать : MYPARAM
к '368134,181956'
в вашем случае.
Вот метод, который я использовал в прошлом, чтобы обойти эту проблему с оператором IN. Он создает список «ИЛИ» на основе количества значений, указанных с параметрами (уникальными). Затем все, что мне нужно было сделать, это добавить параметры в том порядке, в котором они появляются в списке предоставленных значений.
var
FilterValues: TStringList;
i: Integer;
FilterList: String;
Values: String;
FieldName: String;
begin
Query.SQL.Text := 'SELECT * FROM table WHERE '; // set base sql
FieldName := 'some_id'; // field to filter on
Values := '1,4,97'; // list of supplied values in delimited format
FilterList := '';
FilterValues := TStringList.Create; // will get the supplied values so we can loop
try
FilterValues.CommaText := Values;
for i := 0 to FilterValues.Count - 1 do
begin
if FilterList = '' then
FilterList := Format('%s=:param%u', [FieldName, i]) // build the filter list
else
FilterList := Format('%s OR %s=:param%u', [FilterList, FieldName, i]); // and an OR
end;
Query.SQL.Text := Query.SQL.Text + FilterList; // append the OR list to the base sql
// ShowMessage(FilterList); // see what the list looks like.
if Query.ParamCount <> FilterValues.Count then
raise Exception.Create('Param count and Value count differs.'); // check to make sure the supplied values have parameters built for them
for i := 0 to FilterValues.Count - 1 do
begin
Query.Params[i].Value := FilterValues[i]; // now add the values
end;
Query.Open;
finally
FilterValues.Free;
end;
Надеюсь, это поможет.
Параметры являются заполнителями для отдельных значений, это означает, что предложение IN, которое принимает список значений, разделенных запятыми, не может использоваться с параметрами.
Подумайте об этом так: где бы я ни поместил значение, я могу использовать параметр.
Итак, в предложении типа: IN (: param)
я могу привязать переменную к значению, но только к 1 значению, например: IN (4)
Теперь, если вы рассмотрите предложение "IN" value expression ", вы получите строку значений: IN (1, 4, 6) -> это 3 значения с запятыми между ними. Это часть строки SQL, а не часть значения, поэтому ее нельзя связать параметром.
Очевидно, это не то, что вы хотите, но это единственное, что возможно с параметрами.