Как Вы используете cfqueryparam в пункте ORDER BY?

Попробуйте отключить кэш с помощью Dev Tools:

https://developer.chrome.com/devtools/docs/settings#general

7
задан CloudyMusic 20 May 2009 в 18:30
поделиться

5 ответов

К сожалению, вы не можете использовать CFQUERYPARAM непосредственно в предложении Order By.

Если вы хотите использовать Order By динамически но при этом делать это безопасно, вы можете настроить CFSWITCH или аналогичную структуру для изменения вашей переменной SortBy в зависимости от некоторого условия (например, переменной URL). Как всегда, не передавайте никаких значений напрямую от пользователя, просто посмотрите на ввод пользователя и выберите из заранее определенного списка возможных значений на основе этого. Затем просто используйте стандартный синтаксис:

ORDER BY #SortBy#
12
ответ дан 6 December 2019 в 10:53
поделиться

Я просто расширю ответ Аарона. Одна из вещей, которые я делаю, - это использование listfindnocase (), чтобы убедиться, что аргументы, переданные в предложение order by, действительны:

<cfset variables.safeSortColumn = "name">
<cfset variables.safeSortOrder = "desc">

<cfparam name="url.sortcolumn" type="string" default="#variables.safeSortColumn#">
<cfparam name="url.sortorder" type="string" default="#variables.safeSortOrder#">

<cfif listfindnocase("name,age,address", url.sortcolumn)>
    <cfset variables.safeSortColumn = url.sortcolumn>
</cfif>

<cfif listfindnocase("desc,asc", url.sortorder)>
    <cfset variables.safeSortOrder = url.sortorder>
</cfif>

<cfquery>
select *
from mytable
order by #variables.safeSortcolumn# #variables.safeSortorder#
</cfquery>
4
ответ дан 6 December 2019 в 10:53
поделиться

проблема с использованием порядкового значения для ссылки на столбец заключается в том, что это (я считаю) порядковое значение на момент выполнения SQL-оператора создания таблицы - так что вы добавляете столбцы в базу данных таблицы с течением времени, инструмент графического интерфейса, который вы используете для отображения столбцов, может не отражать его фактическое порядковое значение. я бы действительно воздержался от использования cfqueryparam для этого.

Мне ДЕЙСТВИТЕЛЬНО нравится идея использования числа в переменных запроса (url, form), чтобы указать, по какому столбцу сортировать, а затем использовать его в переключателе и преобразовать его в фактическое имя столбца - поэтому вы не показываете имена столбцов пользователю.

что касается того, когда / зачем использовать cfqueryparam, имейте в виду, что это НЕ только проверка ввода и предотвращение SQL-инъекции (хотя это очень хороший бонус) - с cfqueryparam базовый SQL в базу данных отправляется обратно через драйвер с использованием переменных связывания SQL - значений заполнителей, поэтому оптимизатор базы данных может определить, какой индекс использовать в более общем формате ... поэтому, когда вы отправляете инструкцию SQL, подобную этой: SELECT * FROM product WHERE ID = 1 и SELECT * FROM product WHERE ID = 2, оптимизатор запускается оба раза. но с переменными связывания SQL выглядит так: SELECT * FROM product WHERE ID =? (? = 1) и ВЫБРАТЬ * ИЗ продукта ГДЕ ID =? (? = 2), чтобы оптимизатор мог использовать кэшированные результаты первого анализа, чтобы точно знать, какой индекс использовать во втором запросе. в зависимости от сложности SQL и базы данных это может дать ОГРОМНУЮ экономию времени. Джон

2
ответ дан 6 December 2019 в 10:53
поделиться

Относительно комментария об использовании «cfqueryparam в предложении порядка нормально с MySQL». Да, я считаю, что это разрешено с источниками данных MySQL. Хотя используется порядковый номер столбца , а не имя столбца (которое, похоже, вместо этого рассматривается как постоянная строка).

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

<!--- this works --->
<cfset url.sortColumnNumber = "3">
<cfquery name="getDataByPosition" datasource="MySQLDSN">
   SELECT  RecordID, ProductName, DateAdded
   FROM TestTable
   ORDER BY <cfqueryparam value="#url.sortColumnNumber#" cfsqltype="cf_sql_integer"> ASC
</cfquery>
<cfdump var="#getDataByPosition#">

<!--- this does NOT work --->
<cfset url.sortColumnName = "DateAdded">
<cfquery name="getDataByName" datasource="MySQLDSN">
   SELECT  RecordID, ProductName, DateAdded
   FROM    TestTable
   ORDER BY <cfqueryparam value="DateAdded" cfsqltype="cf_sql_varchar"> ASC
</cfquery>
<cfdump var="#getDataByName#">

Обновление: Относительно комментариев к порядковому номеру: Нет, я считаю, что это относится к позиции столбца в списке выбора, а не к базовой таблице. Так что все должно быть хорошо.

Да, я согласен, что защита от внедрения sql не является основной целью cfqueryparam. Так что описание переменных связывания было хорошим дополнением.

0
ответ дан 6 December 2019 в 10:53
поделиться

Подумал, что я бы добавил меньший код для этой проблемы:

<cfset sortColumns = {IncidentID = "IncidentID", AnimalID = "AnimalID", IntakeDate = "IntakeDate", DxDate = "DxDate", OutcomeDate = "OutcomeDate"}>
<cfset sortDirections = {ASC = "ASC", DESC = "DESC"}>

<cfquery datasource="MyDSN" name="qIncidents">
    SELECT IncidentID, AnimalID, IntakeDate, DxDate, OutcomeDate
    FROM Incidents
    WHERE ShelterID = <cfqueryparam cfsqltype="cf_sql_integer" value="#Arguments.ShelterID#">
    ORDER BY #sortColumns[sortBy]# #sortDirections[sortDirection]#
</cfquery>

Где sortBy и sortDirection входят через URL или где-либо еще.

Мне это нравится, потому что он чистый, и вы можете ' t вводить что-либо через предложение ORDER BY.

Есть комментарии?

0
ответ дан 6 December 2019 в 10:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: