Плохо ли использовать cfquery внутри cfloop?

У меня есть массив структуры. Мне нужно вставить все строки из этого массива в таблицу. Поэтому я просто использовал cfquery внутри cfloop для вставки в базу данных.

Некоторые люди предлагали мне не использовать cfquery внутри cfloop, так как каждый раз он будет устанавливать новое соединение с базой данных.

Но в моем случае есть ли способ сделать это без использования cfloop внутри cfquery?


person Deepak Kumar Padhy    schedule 25.02.2014    source источник
comment
Если вы настроили источник данных для поддержки соединений, он не будет создавать новое соединение для каждой итерации.   -  person Miguel-F    schedule 25.02.2014
comment
@Miguel-F: Не могли бы вы объяснить мне немного подробнее? Как настроить источник данных для поддержания соединения.   -  person Deepak Kumar Padhy    schedule 25.02.2014
comment
Почему бы не использовать cfloop внутри cfquery для построения оператора INSERT?   -  person Scott Stroz    schedule 25.02.2014
comment
В настройках источника данных на странице администратора ColdFusion есть возможность сохранить соединение. Вам нужно нажать кнопку «Дополнительные параметры», чтобы увидеть дополнительные параметры.   -  person Miguel-F    schedule 25.02.2014


Ответы (4)


Речь идет не столько о поддержании соединений, сколько об отправке серверу «n» запросов на вставку или обновление данных для каждой итерации в cfloop. Это будет выглядеть нормально при тестировании нескольких записей, но когда вы запустите его в производство, и ваш клиент подтолкнет ваше приложение к просмотру пары сотен строк, тогда вы попадете на сервер базы данных пару сотен раз, как хорошо.

Как предлагает Скотт, вам следует подумать о циклическом построении одного запроса, а не о нескольких обращениях к базе данных. Цикл внутри cfquery имеет то преимущество, что вы можете использовать cfqueryparam, но если вы можете доверять данным, т.е. он уже был очищен, вам может быть проще использовать что-то вроде cfsavecontent для создания вашего запроса и вывода строки внутри cfquery в конце.

person Stephen Moretti    schedule 25.02.2014
comment
Да, та же проблема, в базе данных есть тысячи записей. Это может быть хорошим вариантом для динамического создания всех строк запросов за раз и передачи их в cfquery. - person Deepak Kumar Padhy; 25.02.2014
comment
Договорились о минимизации обращений к базе данных. Однако я не вижу никакой выгоды в построении строки sql вместо использования cfqueryparam. Вы теряете предварительную проверку базы данных, не говоря уже о том, что бремя обеспечения того, чтобы все данные были должным образом очищены (обрабатываются одинарные кавычки и т. д.), теперь являются данными на вас, вместо того, чтобы полагаться на них. проверенные методы jdbc. ИМО, вам гораздо лучше придерживаться cfqueryparam. - person Leigh; 25.02.2014
comment
Хороший совет, кроме ограничения 2100, если он использует SQL Server. - person Henry; 08.09.2015

Я использовал как запрос внутри цикла, так и цикл внутри метода запроса. Хотя наличие цикла внутри запроса теоретически быстрее, это не всегда так. Вы должны попробовать каждый метод и посмотреть, что лучше всего работает в вашей ситуации.

Вот синтаксис цикла внутри запроса с использованием оракула для выбора базы данных.

insert into table
(field1, field2, etc)
select null, null, etc
from dual
where 1 = 2
<cfloop>
union
select <cfqueryparam value="#value1#">
, <cfqueryparam value="#value2#">
etc
from dual
</cfloop>
person Dan Bracuk    schedule 25.02.2014

В зависимости от базы данных преобразуйте массив структур в XML, а затем передайте его как один параметр хранимой процедуре.

В хранимой процедуре выполните INSERT INTO SELECT, где инструкция SELECT выбирает данные из XML-пакета. Таким образом, вы можете вставить сотни или тысячи записей с помощью одного оператора INSERT.

Вот пример.

person Adrian J. Moreno    schedule 25.02.2014

Существует ограничение на количество <CFQUERY><cfloop>... итераций, которые вы можете выполнить при использовании <cfqueryparam>. Это также зависит от производителя. Если вы не знаете, сколько записей вы будете генерировать, лучше удалить <cfqueryparam>, если это безопасно. Убедитесь, что ваши данные поступают из надежных источников и проверены. Этот подход может сэкономить огромное количество времени обработки, потому что это всего один вызов к серверу базы данных, в отличие от внешнего цикла.

person Charles Robertson    schedule 08.09.2015
comment
Я считаю, что вопрос использует другое направление вложенности... у него есть cfquery внутри cfloop. - person Stefan Braun; 08.09.2015