Возникли проблемы с пониманием циклов
Я создал это по какой-то причине, ни один из запросов не обновляется
<cfloop index="i" from="1" to="#ArrayLen(location)#">
<cfif location[i] NEQ "" AND #locationID# EQ "" >
<cfquery Name="UpdateAddActivity" DATASOURCE="#DS#">
INSERT INTO tblProjectLocations
(
projectID,
locationID
)
VALUES
(
#ProjectName#,
#location[i]#
)
</cfquery>
</cfif>
<cfif location[i] EQ "" AND #locationID# NEQ "" >
<cfquery Name="UpdateAddActivity" DATASOURCE="#DS#">
DELETE FROM tblProjectLocations
WHERE locationID = #locationID# AND projectID = #ProjectName#
</cfquery>
</cfif>
</cfloop>
Я зациклен правильно? Мне не кажется, что аккумулятор когда-либо будет обновляться, но циклы создаются таким образом в каждом месте, которое я смотрел.
3 ответа
Ваш тэг cfloop в порядке - вам нужны только атрибуты index/from/to для основного цикла.
index
переменная увеличивается (и цикл повторно обрабатывается) в позиции закрывающего тега. Или, другими словами, код тела выполняется один раз для каждого значения индекса между from
а также to
(Включительно).
Для информации, вы можете изменить приращение по умолчанию (1), указав step
атрибут (хотя это, очевидно, не имеет смысла для цикла массива).
Если ваш код не работает должным образом, вы можете отладить его с помощью тега dump:
<cfloop ... >
...
<cfdump var=#locationID# abort />
...
</cfloop>
abort
Атрибут прекратит обработку - цикл не будет повторяться, и будет возвращено содержимое текущей страницы (это сокращение для указания тега cfabort отдельно.
Вы можете использовать несколько дампов, и label
атрибут, помогающий определить, который есть какой, но, очевидно, при использовании атрибута abort убедитесь, что он есть только у последнего.
Как уже упоминалось locationID
не определен в предоставленном вами фрагменте, поэтому может быть проблема.
Иногда пробелы могут вызывать проблемы - вы можете использовать функцию обрезки, чтобы убедиться, что вы имеете дело с пустыми строками (хотя слепая обертка функций обрезки везде уродлива - всегда старайтесь по возможности избегать введения пробелов).
Ярлык с циклом
Цикл from / to у вас есть только один тип cfloop - есть и другие.
В частности, когда вам не нужен числовой индекс, существует сокращенный цикл массива:
<cfloop index="CurLocation" array=#Location# >
...
</cfloop>
Что эквивалентно:
<cfloop index="i" from=1 to=#ArrayLen(Location)# >
<cfset CurLocation = Location[i] />
...
</cfloop>
Но без неиспользованного i
переменная. (Если вам нужно i
переменная, придерживайтесь от / до.)
Обратите внимание, что внутри функции вы должны почти всегда писать index="local.i"
а также index="local.CurLocation"
чтобы убедиться, что переменные правильно определены. Это не уникально для циклов - оно применяется к любым тегам, которые создают переменные. Вы также можете сделать <cfset var i = 0 />
до цикла сделать то же самое.
Несвязанные вопросы
Есть несколько других проблем с вашим кодом.
Самое главное, что код, который вы показываете, потенциально подвержен риску внедрения SQL. Вы почти никогда не должны писать SQL с пустыми хэшами, а вместо этого параметризировать свои запросы - используя тег cfqueryparam - для решения этой проблемы. (В ситуациях, когда вы не можете использовать параметры (например, в ORDER BY
) убедитесь, что вы правильно обработали любой динамический текст.
Менее важно - это не меняет принцип работы кода, но выдает недостаток опыта и понимания - это лишние хеши вокруг locationID
, Упрощенное объяснение состоит в том, что вам, как правило, нужно только #
s внутри строк (т. е. где содержимое в противном случае будет рассматриваться как текст, а не как значение переменной.)
Если сомневаетесь, посмотрите на свои данные.
<cfoutput>
<cfloop index="i" from="1" to="#ArrayLen(location)#">
i is #i# <br>
<cfif location[i] NEQ "" AND locationID EQ "" >
true location is #location[i]# <br>
<cfelse>
false location [i] is is #location[i]# and
locationid is #locationID# <br>
</cfif>
<cfif location[i] EQ "" AND locationID NEQ "" >
same as above
</cfif>
</cfloop>
</cfoutput>
Тогда вы поймете, почему вы не получаете ожидаемых результатов.
Пока в вашем массиве местоположений есть элементы, цикл будет выполняться, а тег CFLoop будет заботиться о увеличении i.
Я предполагаю, что происходит то, что вы проверяете два условия в цикле и, если ни одно из них не совпадает, никакой код не будет запущен. Вы справляетесь с этим:
location[i] NEQ "" AND #locationID# EQ ""
location[i] EQ "" AND #locationID# NEQ ""
но не эти
location[i] EQ "" AND #locationID# EQ ""
location[i] NEQ "" AND #locationID# NEQ ""
Может ли это быть?